diff --git a/.jazzy.yaml b/.jazzy.yaml index 21effd7c..42d60371 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -5,4 +5,12 @@ root_url: https://techprimate.github.io/TPPDF/ module: TPPDF output: docs theme: fullwidth -xcodebuild_arguments: [-project, 'Example iOS-SwiftPM/Example.xcodeproj', -scheme, 'Example', -sdk, 'iphonesimulator'] +xcodebuild_arguments: + [ + -workspace, + "Examples.xcworkspace", + -scheme, + "Example iOS (SPM)", + -sdk, + "iphonesimulator", + ] diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 00000000..835a8c39 --- /dev/null +++ b/.swiftformat @@ -0,0 +1,85 @@ +--acronyms ID,URL,UUID +--allman false +--anonymousforeach convert +--assetliterals visual-width +--asynccapturing +--beforemarks +--binarygrouping 4,8 +--categorymark "MARK: %c" +--classthreshold 0 +--closingparen balanced +--closurevoid remove +--commas always +--conflictmarkers reject +--decimalgrouping 3,6 +--elseposition same-line +--emptybraces no-space +--enumnamespaces always +--enumthreshold 0 +--exponentcase lowercase +--exponentgrouping disabled +--extensionacl on-extension +--extensionlength 0 +--extensionmark "MARK: - %t + %c" +--fractiongrouping disabled +--fragment false +--funcattributes preserve +--generictypes +--groupedextension "MARK: %c" +--guardelse auto +--header ignore +--hexgrouping 4,8 +--hexliteralcase uppercase +--ifdef indent +--importgrouping alpha +--indent 4 +--indentcase false +--indentstrings false +--lifecycle +--lineaftermarks true +--linebreaks lf +--markcategories true +--markextensions always +--marktypes never +--maxwidth none +--modifierorder +--nevertrailing +--nospaceoperators +--nowrapoperators +--octalgrouping 4,8 +--onelineforeach ignore +--operatorfunc spaced +--organizetypes actor,class,enum,struct +--patternlet hoist +--ranges no-space +--redundanttype infer-locals-only +--self init-only +--selfrequired +--semicolons inline +--shortoptionals always +--smarttabs enabled +--someany true +--stripunusedargs always +--structthreshold 0 +--tabwidth unspecified +--throwcapturing +--trailingclosures +--trimwhitespace always +--typeattributes preserve +--typeblanklines remove +--typemark "MARK: - %t" +--varattributes preserve +--voidtype void +--wraparguments preserve +--wrapcollections preserve +--wrapconditions preserve +--wrapeffects preserve +--wrapenumcases always +--wrapparameters preserve +--wrapreturntype preserve +--wrapternary default +--wraptypealiases preserve +--xcodeindentation enabled +--yodaswap always +--disable blankLineAfterImports,blankLinesBetweenChainedFunctions,wrapMultilineStatementBraces +--enable isEmpty,markTypes diff --git a/.swiftlint.yml b/.swiftlint.yml index a5b89075..a58c8f60 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -2,6 +2,7 @@ disabled_rules: - large_tuple - todo + - inclusive_language excluded: - Carthage - Pods @@ -14,8 +15,6 @@ opt_in_rules: - convenience_type - empty_count - empty_string - - explicit_acl - - explicit_self - file_header - first_where - last_where @@ -29,12 +28,14 @@ opt_in_rules: - multiline_function_chains - redundant_nil_coalescing - static_operator +analyzer_rules: + - explicit_self file_length: - error: 1200 - warning: 500 -force_cast: warning + error: 1200 + warning: 500 +force_cast: warning force_try: - severity: warning + severity: warning identifier_name: excluded: - id @@ -42,17 +43,17 @@ identifier_name: - y - i min_length: - error: 2 - warning: 2 + error: 2 + warning: 2 included: - Source -line_length: 150 -reporter: xcode +line_length: 150 +reporter: xcode type_body_length: - 300 - 400 type_name: max_length: - error: 60 - warning: 50 - min_length: 2 + error: 60 + warning: 50 + min_length: 2 diff --git a/Dangerfile.swift b/Dangerfile.swift index 7fdfc5ff..baf17580 100644 --- a/Dangerfile.swift +++ b/Dangerfile.swift @@ -10,9 +10,9 @@ let sourceChanges = allSourceFiles.contains { $0.hasPrefix("Source") } let isNotTrivial = !danger.github.pullRequest.title.contains("#trivial") if isNotTrivial && noChangelogEntry && sourceChanges { danger.warn(""" - Any changes to library code should be reflected in the Changelog. - Please consider adding a note there. - """) + Any changes to library code should be reflected in the Changelog. + Please consider adding a note there. + """) } // Make it more obvious that a PR is a work in progress and shouldn't be merged yet @@ -30,7 +30,7 @@ if (danger.github.pullRequest.additions ?? 0) > 500 { let addedSwiftLibraryFiles = danger.git.createdFiles.contains { $0.fileType == .swift && $0.hasPrefix("Source") } let deletedSwiftLibraryFiles = danger.git.deletedFiles.contains { $0.fileType == .swift && $0.hasPrefix("Source") } let modifiedCarthageXcodeProject = danger.git.modifiedFiles.contains { $0.contains("TPPDF.xcodeproj") } -if (addedSwiftLibraryFiles || deletedSwiftLibraryFiles) && !modifiedCarthageXcodeProject { +if addedSwiftLibraryFiles || deletedSwiftLibraryFiles, !modifiedCarthageXcodeProject { fail("Added or removed library files require the Carthage Xcode project to be updated.") } @@ -38,10 +38,10 @@ if (addedSwiftLibraryFiles || deletedSwiftLibraryFiles) && !modifiedCarthageXcod let manifests = [ "TPPDF.podspec", "Package.swift", - "Package.resolved" + "Package.resolved", ] let updatedManifests = manifests.filter { manifest in danger.git.modifiedFiles.contains { $0.name == manifest } } -if !updatedManifests.isEmpty && updatedManifests.count != manifests.count { +if !updatedManifests.isEmpty, updatedManifests.count != manifests.count { let notUpdatedManifests = manifests.filter { !updatedManifests.contains($0) } let updatedArticle = updatedManifests.count == 1 ? "The " : "" let updatedVerb = updatedManifests.count == 1 ? "was" : "were" @@ -54,7 +54,7 @@ if !updatedManifests.isEmpty && updatedManifests.count != manifests.count { // Warn when library files has been updated but not tests. let testsUpdated = danger.git.modifiedFiles.contains { $0.hasPrefix("Tests") } -if sourceChanges && !testsUpdated { +if sourceChanges, !testsUpdated { warn("The library files were changed, but the tests remained unmodified. Consider updating or adding to the tests to match the library changes.") } diff --git a/Documentation/Usage.md b/Documentation/Usage.md index 3c9147f5..a396733f 100644 --- a/Documentation/Usage.md +++ b/Documentation/Usage.md @@ -504,7 +504,7 @@ Also each cell can have a `margin` which is the distance between the cell frame document.add(table: table) ``` -## Multi-Column Sections +### Multi-Column Sections A multi-column section is a nested container. You create the section with an amount of columns and their relative width, add objects to each column and then add the whole section to the document. diff --git a/Example iOS-Carthage/Example.xcodeproj/project.pbxproj b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.pbxproj similarity index 97% rename from Example iOS-Carthage/Example.xcodeproj/project.pbxproj rename to Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.pbxproj index a5a0e650..c81d6afa 100644 --- a/Example iOS-Carthage/Example.xcodeproj/project.pbxproj +++ b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.pbxproj @@ -46,7 +46,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 607FACD01AFB9204008FA782 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD01AFB9204008FA782 /* Example_iOS-Carthage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example_iOS-Carthage.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -110,7 +110,7 @@ 607FACD11AFB9204008FA782 /* Products */ = { isa = PBXGroup; children = ( - 607FACD01AFB9204008FA782 /* Example.app */, + 607FACD01AFB9204008FA782 /* Example_iOS-Carthage.app */, ); name = Products; sourceTree = ""; @@ -246,9 +246,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 607FACCF1AFB9204008FA782 /* Example */ = { + 607FACCF1AFB9204008FA782 /* Example_iOS-Carthage */ = { isa = PBXNativeTarget; - buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-Carthage" */; buildPhases = ( 607FACCC1AFB9204008FA782 /* Sources */, 607FACCD1AFB9204008FA782 /* Frameworks */, @@ -259,11 +259,11 @@ ); dependencies = ( ); - name = Example; + name = "Example_iOS-Carthage"; packageProductDependencies = ( ); productName = TPPDF; - productReference = 607FACD01AFB9204008FA782 /* Example.app */; + productReference = 607FACD01AFB9204008FA782 /* Example_iOS-Carthage.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -283,7 +283,7 @@ }; }; }; - buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-Carthage" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; @@ -298,7 +298,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 607FACCF1AFB9204008FA782 /* Example */, + 607FACCF1AFB9204008FA782 /* Example_iOS-Carthage */, ); }; /* End PBXProject section */ @@ -559,7 +559,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */ = { + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-Carthage" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACED1AFB9204008FA782 /* Debug */, @@ -568,7 +568,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */ = { + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-Carthage" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACF01AFB9204008FA782 /* Debug */, diff --git a/Example iOS-Carthage/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Example iOS-Carthage/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example iOS-Carthage/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Example iOS-Carthage/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Example iOS-Carthage/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/xcshareddata/xcschemes/Example iOS (Carthage).xcscheme similarity index 79% rename from Example iOS-Carthage/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/xcshareddata/xcschemes/Example iOS (Carthage).xcscheme index 3ffaa3a4..6b9bb0df 100644 --- a/Example iOS-Carthage/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example iOS-Carthage/Example_iOS-Carthage.xcodeproj/xcshareddata/xcschemes/Example iOS (Carthage).xcscheme @@ -1,6 +1,6 @@ + BuildableName = "Example_iOS-Carthage.app" + BlueprintName = "Example_iOS-Carthage" + ReferencedContainer = "container:Example_iOS-Carthage.xcodeproj"> @@ -45,9 +45,9 @@ + BuildableName = "Example_iOS-Carthage.app" + BlueprintName = "Example_iOS-Carthage" + ReferencedContainer = "container:Example_iOS-Carthage.xcodeproj"> @@ -62,9 +62,9 @@ + BuildableName = "Example_iOS-Carthage.app" + BlueprintName = "Example_iOS-Carthage" + ReferencedContainer = "container:Example_iOS-Carthage.xcodeproj"> diff --git a/Example iOS-Cocoapods/Example.xcodeproj/project.pbxproj b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.pbxproj similarity index 97% rename from Example iOS-Cocoapods/Example.xcodeproj/project.pbxproj rename to Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.pbxproj index aff03743..272485ff 100644 --- a/Example iOS-Cocoapods/Example.xcodeproj/project.pbxproj +++ b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.pbxproj @@ -48,7 +48,7 @@ /* Begin PBXFileReference section */ 4A563E64F9EAA2CFA08F14DB /* Pods-TPPDF_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TPPDF_Example.release.xcconfig"; path = "Target Support Files/Pods-TPPDF_Example/Pods-TPPDF_Example.release.xcconfig"; sourceTree = ""; }; 53E4A2A5504D7EA42E9FAB88 /* Pods-TPPDF_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TPPDF_Example.debug.xcconfig"; path = "Target Support Files/Pods-TPPDF_Example/Pods-TPPDF_Example.debug.xcconfig"; sourceTree = ""; }; - 607FACD01AFB9204008FA782 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD01AFB9204008FA782 /* Example_iOS-Cocoapods.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example_iOS-Cocoapods.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -126,7 +126,7 @@ 607FACD11AFB9204008FA782 /* Products */ = { isa = PBXGroup; children = ( - 607FACD01AFB9204008FA782 /* Example.app */, + 607FACD01AFB9204008FA782 /* Example_iOS-Cocoapods.app */, ); name = Products; sourceTree = ""; @@ -260,9 +260,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 607FACCF1AFB9204008FA782 /* Example */ = { + 607FACCF1AFB9204008FA782 /* Example_iOS-Cocoapods */ = { isa = PBXNativeTarget; - buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-Cocoapods" */; buildPhases = ( E638F0EEF355F6576E268BF8 /* [CP] Check Pods Manifest.lock */, 607FACCC1AFB9204008FA782 /* Sources */, @@ -274,9 +274,9 @@ ); dependencies = ( ); - name = Example; + name = "Example_iOS-Cocoapods"; productName = TPPDF; - productReference = 607FACD01AFB9204008FA782 /* Example.app */; + productReference = 607FACD01AFB9204008FA782 /* Example_iOS-Cocoapods.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -296,7 +296,7 @@ }; }; }; - buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-Cocoapods" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; @@ -309,7 +309,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 607FACCF1AFB9204008FA782 /* Example */, + 607FACCF1AFB9204008FA782 /* Example_iOS-Cocoapods */, ); }; /* End PBXProject section */ @@ -584,7 +584,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */ = { + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-Cocoapods" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACED1AFB9204008FA782 /* Debug */, @@ -593,7 +593,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */ = { + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-Cocoapods" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACF01AFB9204008FA782 /* Debug */, diff --git a/Example iOS-Cocoapods/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Example iOS-Cocoapods/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example iOS-Cocoapods/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Example iOS-Cocoapods/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Example iOS-Cocoapods/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/xcshareddata/xcschemes/Example iOS (Cocoapods).xcscheme similarity index 79% rename from Example iOS-Cocoapods/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/xcshareddata/xcschemes/Example iOS (Cocoapods).xcscheme index 3ffaa3a4..78a381cc 100644 --- a/Example iOS-Cocoapods/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example iOS-Cocoapods/Example_iOS-Cocoapods.xcodeproj/xcshareddata/xcschemes/Example iOS (Cocoapods).xcscheme @@ -1,6 +1,6 @@ + BuildableName = "Example_iOS-Cocoapods.app" + BlueprintName = "Example_iOS-Cocoapods" + ReferencedContainer = "container:Example_iOS-Cocoapods.xcodeproj"> @@ -45,9 +45,9 @@ + BuildableName = "Example_iOS-Cocoapods.app" + BlueprintName = "Example_iOS-Cocoapods" + ReferencedContainer = "container:Example_iOS-Cocoapods.xcodeproj"> @@ -62,9 +62,9 @@ + BuildableName = "Example_iOS-Cocoapods.app" + BlueprintName = "Example_iOS-Cocoapods" + ReferencedContainer = "container:Example_iOS-Cocoapods.xcodeproj"> diff --git a/Example iOS-SwiftPM/Example.xcodeproj/project.pbxproj b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.pbxproj similarity index 94% rename from Example iOS-SwiftPM/Example.xcodeproj/project.pbxproj rename to Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.pbxproj index 37a37320..71d875fc 100644 --- a/Example iOS-SwiftPM/Example.xcodeproj/project.pbxproj +++ b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -47,7 +47,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 607FACD01AFB9204008FA782 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD01AFB9204008FA782 /* Example_iOS-SPM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example_iOS-SPM.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -113,7 +113,7 @@ 607FACD11AFB9204008FA782 /* Products */ = { isa = PBXGroup; children = ( - 607FACD01AFB9204008FA782 /* Example.app */, + 607FACD01AFB9204008FA782 /* Example_iOS-SPM.app */, ); name = Products; sourceTree = ""; @@ -247,9 +247,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 607FACCF1AFB9204008FA782 /* Example */ = { + 607FACCF1AFB9204008FA782 /* Example_iOS-SPM */ = { isa = PBXNativeTarget; - buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-SPM" */; buildPhases = ( 607FACCC1AFB9204008FA782 /* Sources */, D4E6F9A21FA732720049890F /* Swift Lint */, @@ -260,12 +260,12 @@ ); dependencies = ( ); - name = Example; + name = "Example_iOS-SPM"; packageProductDependencies = ( D454C07C249A796A0001E4CC /* TPPDF */, ); productName = TPPDF; - productReference = 607FACD01AFB9204008FA782 /* Example.app */; + productReference = 607FACD01AFB9204008FA782 /* Example_iOS-SPM.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -274,8 +274,9 @@ 607FACC81AFB9204008FA782 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1010; - LastUpgradeCheck = 1120; + LastUpgradeCheck = 1530; ORGANIZATIONNAME = "techprimate GmbH"; TargetAttributes = { 607FACCF1AFB9204008FA782 = { @@ -285,7 +286,7 @@ }; }; }; - buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-SPM" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; @@ -300,7 +301,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 607FACCF1AFB9204008FA782 /* Example */, + 607FACCF1AFB9204008FA782 /* Example_iOS-SPM */, ); }; /* End PBXProject section */ @@ -340,7 +341,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n if [-z \"$CI\"]; then\n echo \"Skipping SwiftLint as running on CI...\"\n else\n cd ../\n \"swiftlint\" --config .swiftlint.yml\n fi\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + shellScript = "if [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which swiftlint > /dev/null; then\n if [-z \"$CI\"]; then\n echo \"Skipping SwiftLint as running on CI...\"\n else\n swiftlint --config \"$SRCROOT/../.swiftlint.yml\" --fix && swiftlint --config \"$SRCROOT/../.swiftlint.yml\"\n fi\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -421,6 +422,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -431,6 +433,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -446,7 +449,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -478,6 +481,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -488,6 +492,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -496,7 +501,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -514,9 +519,11 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_PARAMETER = YES; INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -537,9 +544,11 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_PARAMETER = YES; INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -555,7 +564,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */ = { + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example_iOS-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACED1AFB9204008FA782 /* Debug */, @@ -564,7 +573,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example" */ = { + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Example_iOS-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( 607FACF01AFB9204008FA782 /* Debug */, diff --git a/Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from Example iOS-SwiftPM/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Example iOS-SwiftPM/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/xcshareddata/xcschemes/Example iOS (SPM).xcscheme similarity index 81% rename from Example iOS-SwiftPM/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/xcshareddata/xcschemes/Example iOS (SPM).xcscheme index 3ffaa3a4..16645c53 100644 --- a/Example iOS-SwiftPM/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example iOS-SwiftPM/Example_iOS-SPM.xcodeproj/xcshareddata/xcschemes/Example iOS (SPM).xcscheme @@ -1,6 +1,6 @@ + BuildableName = "Example_iOS-SPM.app" + BlueprintName = "Example_iOS-SPM" + ReferencedContainer = "container:Example_iOS-SPM.xcodeproj"> @@ -45,9 +45,9 @@ + BuildableName = "Example_iOS-SPM.app" + BlueprintName = "Example_iOS-SPM" + ReferencedContainer = "container:Example_iOS-SPM.xcodeproj"> @@ -62,9 +62,9 @@ + BuildableName = "Example_iOS-SPM.app" + BlueprintName = "Example_iOS-SPM" + ReferencedContainer = "container:Example_iOS-SPM.xcodeproj"> diff --git a/Example macOS/Example/AppDelegate.swift b/Example macOS/Example/AppDelegate.swift index fa9d3f30..8b22eb55 100644 --- a/Example macOS/Example/AppDelegate.swift +++ b/Example macOS/Example/AppDelegate.swift @@ -11,17 +11,17 @@ import SwiftUI @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - var window: NSWindow! - func applicationDidFinishLaunching(_ aNotification: Notification) { + func applicationDidFinishLaunching(_: Notification) { let contentView = ContentView() window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 800, height: 600), styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, - defer: false) + defer: false + ) window.title = "TPPDF Examples" window.center() window.setFrameAutosaveName("Main Window") @@ -30,7 +30,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { window.setFrameAutosaveName("main") } - func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { true } } diff --git a/Example macOS/Example/UI/ContentView.swift b/Example macOS/Example/UI/ContentView.swift index 4c01cd96..d8f225ed 100644 --- a/Example macOS/Example/UI/ContentView.swift +++ b/Example macOS/Example/UI/ContentView.swift @@ -6,19 +6,16 @@ // Copyright © 2022 techprimate GmbH. All rights reserved. // -import SwiftUI import Combine +import SwiftUI import TPPDF class ContentViewModel: ObservableObject { - @Published var url: URL? @State var selectedFactory = Examples.defaultFactory - } struct ContentView: View { - @ObservedObject var viewModel = ContentViewModel() var body: some View { diff --git a/Example macOS/Example/UI/DetailView.swift b/Example macOS/Example/UI/DetailView.swift index 2c66b629..62233c64 100644 --- a/Example macOS/Example/UI/DetailView.swift +++ b/Example macOS/Example/UI/DetailView.swift @@ -6,11 +6,10 @@ // Copyright © 2022 techprimate GmbH. All rights reserved. // -import TPPDF import SwiftUI +import TPPDF struct DetailView: View { - @State var example: Example @State var generator: PDFGeneratorProtocol! @State var isGenerated = false @@ -38,7 +37,7 @@ struct DetailView: View { PDFKitRepresentedView(url: url) .onAppear { self.generatePDF(force: false) - } + } } } @@ -54,8 +53,8 @@ struct DetailView: View { } generator.debug = true - observer = generator.progress.observe(\.completedUnitCount) { (p, v) in - self.progressValue = p.fractionCompleted + observer = generator.progress.observe(\.completedUnitCount) { progress, _ in + self.progressValue = progress.fractionCompleted } DispatchQueue.global(qos: .background).async { diff --git a/Example macOS/Example/UI/PDFView+SwiftUI.swift b/Example macOS/Example/UI/PDFView+SwiftUI.swift index f18de3c2..0c46ea78 100644 --- a/Example macOS/Example/UI/PDFView+SwiftUI.swift +++ b/Example macOS/Example/UI/PDFView+SwiftUI.swift @@ -10,56 +10,51 @@ import PDFKit import SwiftUI #if os(macOS) -import AppKit - -struct PDFKitRepresentedView: NSViewRepresentable { - - var url: URL? - - init(url: URL?) { - self.url = url - } - - func makeNSView(context: NSViewRepresentableContext) -> PDFKitRepresentedView.NSViewType { - let pdfView = PDFView() - if let url = self.url { - pdfView.document = PDFDocument(url: url) - } else { - pdfView.document = nil + import AppKit + + struct PDFKitRepresentedView: NSViewRepresentable { + var url: URL? + + func makeNSView(context _: NSViewRepresentableContext) -> PDFKitRepresentedView.NSViewType { + let pdfView = PDFView() + if let url = url { + pdfView.document = PDFDocument(url: url) + } else { + pdfView.document = nil + } + return pdfView } - return pdfView - } - func updateNSView(_ nsView: NSView, context: NSViewRepresentableContext) { - guard let pdfView = nsView as? PDFView else { - return - } - if let url = self.url { - pdfView.document = PDFDocument(url: url) - } else { - pdfView.document = nil + func updateNSView(_ nsView: NSView, context _: NSViewRepresentableContext) { + guard let pdfView = nsView as? PDFView else { + return + } + if let url = url { + pdfView.document = PDFDocument(url: url) + } else { + pdfView.document = nil + } } } -} #elseif os(iOS) -import UIKit + import UIKit -struct PDFKitRepresentedView: UIViewRepresentable { - let url: URL + struct PDFKitRepresentedView: UIViewRepresentable { + let url: URL - init(_ url: URL) { - self.url = url - } + init(_ url: URL) { + self.url = url + } - func makeUIView(context: UIViewRepresentableContext) -> PDFKitRepresentedView.UIViewType { - // Create a `PDFView` and set its `PDFDocument`. - let pdfView = PDFView() - pdfView.document = PDFDocument(url: self.url) - return pdfView - } + func makeUIView(context _: UIViewRepresentableContext) -> PDFKitRepresentedView.UIViewType { + // Create a `PDFView` and set its `PDFDocument`. + let pdfView = PDFView() + pdfView.document = PDFDocument(url: url) + return pdfView + } - func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) {} -} + func updateUIView(_: UIView, context _: UIViewRepresentableContext) {} + } #endif diff --git a/Example macOS/Example/UI/ProgressBar.swift b/Example macOS/Example/UI/ProgressBar.swift index bde77fb4..e82cac87 100644 --- a/Example macOS/Example/UI/ProgressBar.swift +++ b/Example macOS/Example/UI/ProgressBar.swift @@ -13,9 +13,9 @@ struct ProgressBar: View { var body: some View { GeometryReader { geometry in - ZStack(alignment: .leading) { + ZStack(alignment: .leading) { Rectangle() - .frame(width: geometry.size.width , height: geometry.size.height) + .frame(width: geometry.size.width, height: geometry.size.height) .opacity(0.3) .foregroundColor(Color(.systemTeal)) diff --git a/Example macOS/Example.xcodeproj/project.pbxproj b/Example macOS/Example_macOS-SPM.xcodeproj/project.pbxproj similarity index 94% rename from Example macOS/Example.xcodeproj/project.pbxproj rename to Example macOS/Example_macOS-SPM.xcodeproj/project.pbxproj index 01dc0859..25baea87 100644 --- a/Example macOS/Example.xcodeproj/project.pbxproj +++ b/Example macOS/Example_macOS-SPM.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -51,7 +51,7 @@ /* Begin PBXFileReference section */ D45C42EC24A3C1970040FE37 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = ""; }; D45C42EE24A3C1B80040FE37 /* DetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = ""; }; - D48C538524A269F400D7A3DD /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D48C538524A269F400D7A3DD /* Example_macOS-SPM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example_macOS-SPM.app"; sourceTree = BUILT_PRODUCTS_DIR; }; D48C538824A269F400D7A3DD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D48C538A24A269F400D7A3DD /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; D48C538C24A269F500D7A3DD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -129,7 +129,7 @@ D48C538624A269F400D7A3DD /* Products */ = { isa = PBXGroup; children = ( - D48C538524A269F400D7A3DD /* Example.app */, + D48C538524A269F400D7A3DD /* Example_macOS-SPM.app */, ); name = Products; sourceTree = ""; @@ -245,10 +245,11 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - D48C538424A269F400D7A3DD /* Example */ = { + D48C538424A269F400D7A3DD /* Example_macOS-SPM */ = { isa = PBXNativeTarget; - buildConfigurationList = D48C539824A269F500D7A3DD /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = D48C539824A269F500D7A3DD /* Build configuration list for PBXNativeTarget "Example_macOS-SPM" */; buildPhases = ( + D4E30B4D2BD7044F00BB7AC4 /* SwiftLint */, D48C538124A269F400D7A3DD /* Sources */, D48C538224A269F400D7A3DD /* Frameworks */, D48C538324A269F400D7A3DD /* Resources */, @@ -257,12 +258,12 @@ ); dependencies = ( ); - name = Example; + name = "Example_macOS-SPM"; packageProductDependencies = ( D48C53DB24A26E5400D7A3DD /* TPPDF */, ); productName = Example; - productReference = D48C538524A269F400D7A3DD /* Example.app */; + productReference = D48C538524A269F400D7A3DD /* Example_macOS-SPM.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -271,8 +272,9 @@ D48C537D24A269F400D7A3DD /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1150; - LastUpgradeCheck = 1230; + LastUpgradeCheck = 1530; ORGANIZATIONNAME = "techprimate GmbH"; TargetAttributes = { D48C538424A269F400D7A3DD = { @@ -280,7 +282,7 @@ }; }; }; - buildConfigurationList = D48C538024A269F400D7A3DD /* Build configuration list for PBXProject "Example" */; + buildConfigurationList = D48C538024A269F400D7A3DD /* Build configuration list for PBXProject "Example_macOS-SPM" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; @@ -293,7 +295,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - D48C538424A269F400D7A3DD /* Example */, + D48C538424A269F400D7A3DD /* Example_macOS-SPM */, ); }; /* End PBXProject section */ @@ -320,6 +322,27 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + D4E30B4D2BD7044F00BB7AC4 /* SwiftLint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = SwiftLint; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which swiftlint > /dev/null; then\n if [-z \"$CI\"]; then\n echo \"Skipping SwiftLint as running on CI...\"\n else\n swiftlint --config \"$SRCROOT/../.swiftlint.yml\" --fix && swiftlint --config \"$SRCROOT/../.swiftlint.yml\"\n fi\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ D48C538124A269F400D7A3DD /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -402,6 +425,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -463,6 +487,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -491,10 +516,12 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\""; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -516,10 +543,12 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\""; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -536,7 +565,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - D48C538024A269F400D7A3DD /* Build configuration list for PBXProject "Example" */ = { + D48C538024A269F400D7A3DD /* Build configuration list for PBXProject "Example_macOS-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( D48C539624A269F500D7A3DD /* Debug */, @@ -545,7 +574,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D48C539824A269F500D7A3DD /* Build configuration list for PBXNativeTarget "Example" */ = { + D48C539824A269F500D7A3DD /* Build configuration list for PBXNativeTarget "Example_macOS-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( D48C539924A269F500D7A3DD /* Debug */, diff --git a/Example macOS/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Example macOS/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example macOS/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Example macOS/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Example macOS/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from Example macOS/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to Example macOS/Example_macOS-SPM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Example macOS/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example macOS/Example_macOS-SPM.xcodeproj/xcshareddata/xcschemes/Example macOS (SPM).xcscheme similarity index 69% rename from Example macOS/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Example macOS/Example_macOS-SPM.xcodeproj/xcshareddata/xcschemes/Example macOS (SPM).xcscheme index 66c0a0d7..359b3050 100644 --- a/Example macOS/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example macOS/Example_macOS-SPM.xcodeproj/xcshareddata/xcschemes/Example macOS (SPM).xcscheme @@ -1,26 +1,10 @@ - - - - - - + BuildableName = "Example_macOS-SPM.app" + BlueprintName = "Example_macOS-SPM" + ReferencedContainer = "container:Example_macOS-SPM.xcodeproj"> @@ -89,16 +73,6 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - - - - diff --git a/Examples.xcworkspace/contents.xcworkspacedata b/Examples.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..03bb9312 --- /dev/null +++ b/Examples.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..e5921572 --- /dev/null +++ b/Examples.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,43 @@ +{ + "object": { + "pins": [ + { + "package": "CwlCatchException", + "repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git", + "state": { + "branch": null, + "revision": "3ef6999c73b6938cc0da422f2c912d0158abb0a0", + "version": "2.2.0" + } + }, + { + "package": "CwlPreconditionTesting", + "repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git", + "state": { + "branch": null, + "revision": "2ef56b2caf25f55fa7eef8784c30d5a767550f54", + "version": "2.2.1" + } + }, + { + "package": "Nimble", + "repositoryURL": "https://github.com/Quick/Nimble", + "state": { + "branch": null, + "revision": "c93f16c25af5770f0d3e6af27c9634640946b068", + "version": "9.2.1" + } + }, + { + "package": "Quick", + "repositoryURL": "https://github.com/Quick/Quick", + "state": { + "branch": null, + "revision": "8cce6acd38f965f5baa3167b939f86500314022b", + "version": "3.1.2" + } + } + ] + }, + "version": 1 +} diff --git a/Package.resolved b/Package.resolved index c32f627b..e5921572 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git", "state": { "branch": null, - "revision": "35f9e770f54ce62dd8526470f14c6e137cef3eea", - "version": "2.1.1" + "revision": "3ef6999c73b6938cc0da422f2c912d0158abb0a0", + "version": "2.2.0" } }, { @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git", "state": { "branch": null, - "revision": "c21f7bab5ca8eee0a9998bbd17ca1d0eb45d4688", - "version": "2.1.0" + "revision": "2ef56b2caf25f55fa7eef8784c30d5a767550f54", + "version": "2.2.1" } }, { diff --git a/Package.swift b/Package.swift index 0b04ec07..f3b5e8ea 100644 --- a/Package.swift +++ b/Package.swift @@ -6,28 +6,28 @@ let package = Package( name: "TPPDF", platforms: [ .iOS(.v9), - .macOS(.v10_14) + .macOS(.v10_14), ], products: [ .library(name: "TPPDF", targets: ["TPPDF"]), ], dependencies: [ .package(url: "https://github.com/Quick/Quick", .exact("3.1.2")), - .package(url: "https://github.com/Quick/Nimble", .exact("9.2.1")), + .package(url: "https://github.com/Quick/Nimble", .exact("9.2.1")), ], targets: [ .target(name: "TPPDF", path: "Source"), .testTarget(name: "TPPDFTests", dependencies: [ "TPPDF", "Quick", - "Nimble" + "Nimble", ], resources: [ .copy("resources/sample.pdf"), ]), .testTarget(name: "TPPDFIntegrationTests", dependencies: [ "TPPDF", "Quick", - "Nimble" + "Nimble", ], resources: [ .copy("resources/50-pages.pdf"), ]), diff --git a/Shared iOS/UI/AppDelegate.swift b/Shared iOS/UI/AppDelegate.swift index acb255ad..14aded76 100644 --- a/Shared iOS/UI/AppDelegate.swift +++ b/Shared iOS/UI/AppDelegate.swift @@ -10,7 +10,5 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - } diff --git a/Shared iOS/UI/ExamplesListViewController.swift b/Shared iOS/UI/ExamplesListViewController.swift index 040eb9b7..c21308c0 100644 --- a/Shared iOS/UI/ExamplesListViewController.swift +++ b/Shared iOS/UI/ExamplesListViewController.swift @@ -10,12 +10,11 @@ import Foundation import UIKit class ExamplesListViewController: UITableViewController { - - override func numberOfSections(in tableView: UITableView) -> Int { + override func numberOfSections(in _: UITableView) -> Int { return Examples.factories.count } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int { return Examples.factories[section].examples.count } @@ -30,7 +29,7 @@ class ExamplesListViewController: UITableViewController { return cell } - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? { return Examples.factories[section].header } @@ -40,7 +39,7 @@ class ExamplesListViewController: UITableViewController { } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "show-example", let dest = segue.destination as? ViewController, let index = sender as? IndexPath { + if segue.identifier == "show-example", let dest = segue.destination as? ViewController, let index = sender as? IndexPath { let section = Examples.factories[index.section].examples let item = section[index.row] diff --git a/Shared iOS/UI/ViewController.swift b/Shared iOS/UI/ViewController.swift index 798e1c46..440689d7 100644 --- a/Shared iOS/UI/ViewController.swift +++ b/Shared iOS/UI/ViewController.swift @@ -6,13 +6,12 @@ // Copyright © 2019 Philip Niedertscheider. All rights reserved. // -import UIKit import TPPDF +import UIKit class ViewController: UIViewController { - - @IBOutlet weak var webView: UIWebView! - @IBOutlet weak var progressView: UIProgressView! + @IBOutlet var webView: UIWebView! + @IBOutlet var progressView: UIProgressView! var progressObserver: NSObjectProtocol! @@ -38,7 +37,7 @@ class ViewController: UIViewController { print("Preparation took: " + TimeUtils.stringFromTimeInterval(interval: CFAbsoluteTimeGetCurrent() - startTime)) startTime = CFAbsoluteTimeGetCurrent() /* ---- Execution Metrics ---- */ - + var generator: PDFGeneratorProtocol if documents.count > 1 { generator = PDFMultiDocumentGenerator(documents: documents) @@ -47,15 +46,15 @@ class ViewController: UIViewController { } generator.debug = exampleFactory is ExperimentFactory - self.progressView.observedProgress = generator.progress - observer = generator.progress.observe(\.completedUnitCount) { (p, _) in + progressView.observedProgress = generator.progress + observer = generator.progress.observe(\.completedUnitCount) { p, _ in print(p.localizedDescription ?? "") } DispatchQueue.global(qos: .background).async { do { let url = try generator.generateURL(filename: "Example.pdf") print("Output URL:", url) - + /* ---- Execution Metrics ---- */ print("Generation took: " + TimeUtils.stringFromTimeInterval(interval: CFAbsoluteTimeGetCurrent() - startTime)) /* ---- Execution Metrics ---- */ diff --git a/Shared/Examples/DocumentSettingsExampleFactory.swift b/Shared/Examples/DocumentSettingsExampleFactory.swift index 4b95b16e..bf4bc5c5 100644 --- a/Shared/Examples/DocumentSettingsExampleFactory.swift +++ b/Shared/Examples/DocumentSettingsExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class DocumentSettingsExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) document.background.color = .green diff --git a/Shared/Examples/Examples.swift b/Shared/Examples/Examples.swift index ad7ea7e2..95dfdc29 100644 --- a/Shared/Examples/Examples.swift +++ b/Shared/Examples/Examples.swift @@ -9,21 +9,16 @@ import Foundation struct ExampleSection { - let header: String let examples: [Example] - } struct Example { - let name: String let factory: ExampleFactory - } enum Examples { - static var factories: [ExampleSection] { [ .init(header: "Popular Examples", examples: [ @@ -42,11 +37,11 @@ enum Examples { .init(name: "Pagination", factory: PaginationExampleFactory()), .init(name: "Text Styles", factory: TextStylesExampleFactory()), .init(name: "External Documents", factory: ExternalDocumentExampleFactory()), - .init(name: "Object Attributes", factory: ObjectAttributesExampleFactory()) + .init(name: "Object Attributes", factory: ObjectAttributesExampleFactory()), ]), .init(header: "Developer Examples", examples: [ .init(name: "Experiment", factory: ExperimentFactory()), - ]) + ]), ] } @@ -54,4 +49,3 @@ enum Examples { return factories[1].examples[0] } } - diff --git a/Shared/Examples/ExperimentFactory.swift b/Shared/Examples/ExperimentFactory.swift index bbdc81c5..b6778e04 100644 --- a/Shared/Examples/ExperimentFactory.swift +++ b/Shared/Examples/ExperimentFactory.swift @@ -6,11 +6,10 @@ // Copyright © 2022 techprimate GmbH. All rights reserved. // -import TPPDF import Foundation +import TPPDF class ExperimentFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -20,15 +19,15 @@ class ExperimentFactory: ExampleFactory { let featureList = PDFList(indentations: [ (pre: 10.0, past: 20.0), (pre: 20.0, past: 20.0), - (pre: 40.0, past: 20.0) + (pre: 40.0, past: 20.0), ]) // By adding the item first to a list item with the dot symbol, all of them will inherit it featureList .addItem(PDFListItem(symbol: .dot) - .addItems(items.map({ item in - PDFListItem(content: item) - }))) + .addItems(items.map { item in + PDFListItem(content: item) + })) document.add(list: featureList) document.add(space: 20) @@ -37,13 +36,13 @@ class ExperimentFactory: ExampleFactory { let weirdIndentationList = PDFList(indentations: [ (pre: 10.0, past: 20.0), (pre: 40.0, past: 30.0), - (pre: 20.0, past: 50.0) + (pre: 20.0, past: 50.0), ]) weirdIndentationList - .addItems(items.enumerated().map({ arg in + .addItems(items.enumerated().map { arg in PDFListItem(symbol: .numbered(value: "\(arg.offset + 1)"), content: arg.element) - })) + }) document.add(list: weirdIndentationList) return [document] diff --git a/Shared/Examples/ExternalDocumentExampleFactory.swift b/Shared/Examples/ExternalDocumentExampleFactory.swift index bcb82e9a..89e1736f 100644 --- a/Shared/Examples/ExternalDocumentExampleFactory.swift +++ b/Shared/Examples/ExternalDocumentExampleFactory.swift @@ -10,7 +10,6 @@ import Foundation import TPPDF class ExternalDocumentExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) diff --git a/Shared/Examples/GroupExampleFactory.swift b/Shared/Examples/GroupExampleFactory.swift index 83f49da3..95cd1ec8 100644 --- a/Shared/Examples/GroupExampleFactory.swift +++ b/Shared/Examples/GroupExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class GroupExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) diff --git a/Shared/Examples/HeaderFooterExampleFactory.swift b/Shared/Examples/HeaderFooterExampleFactory.swift index 4955da7a..382ec1e8 100644 --- a/Shared/Examples/HeaderFooterExampleFactory.swift +++ b/Shared/Examples/HeaderFooterExampleFactory.swift @@ -10,7 +10,6 @@ import Foundation import TPPDF class HeaderFooterExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -34,9 +33,8 @@ class HeaderFooterExampleFactory: ExampleFactory { document.add(.headerRight, textObject: PDFSimpleText(text: "Header Right 2")) document.add(.headerRight, textObject: PDFSimpleText(text: "Header Right 3")) - document.add(text: "Random text, otherwise the headers and footers won't be visible") - + return [document] } } diff --git a/Shared/Examples/ImageExampleFactory.swift b/Shared/Examples/ImageExampleFactory.swift index ee881fe5..c1d0fb7a 100644 --- a/Shared/Examples/ImageExampleFactory.swift +++ b/Shared/Examples/ImageExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class ImageExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -41,7 +40,6 @@ class ImageExampleFactory: ExampleFactory { .foregroundColor: Color(red: 0.171875, green: 0.2421875, blue: 0.3125, alpha: 1.0), ] - // Create an image collage with captions let images = [ @@ -54,7 +52,7 @@ class ImageExampleFactory: ExampleFactory { attributes: captionAttributes))), PDFImage(image: Image(named: "Image-3.jpg")!, caption: PDFAttributedText(text: NSAttributedString(string: "Fireworks", - attributes: captionAttributes))) + attributes: captionAttributes))), ], [ PDFImage(image: Image(named: "Image-3.jpg")!, @@ -63,7 +61,7 @@ class ImageExampleFactory: ExampleFactory { PDFImage(image: Image(named: "Image-4.jpg")!, caption: PDFAttributedText(text: NSAttributedString(string: "Field", attributes: captionAttributes))), - ] + ], ] // As an example we can set a tag to the first image, so we can identify in our delegation methods diff --git a/Shared/Examples/LineSeparatorExampleFactory.swift b/Shared/Examples/LineSeparatorExampleFactory.swift index ce84012c..39c41391 100644 --- a/Shared/Examples/LineSeparatorExampleFactory.swift +++ b/Shared/Examples/LineSeparatorExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class LineSeparatorExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) diff --git a/Shared/Examples/ListExampleFactory.swift b/Shared/Examples/ListExampleFactory.swift index 5b795aa6..ae14f87c 100644 --- a/Shared/Examples/ListExampleFactory.swift +++ b/Shared/Examples/ListExampleFactory.swift @@ -9,7 +9,6 @@ import TPPDF class ListExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -22,22 +21,22 @@ class ListExampleFactory: ExampleFactory { "Customizable pagination", "Fully editable header and footer", "Simple image positioning and rendering", - "Image captions" + "Image captions", ] // Simple bullet point list let featureList = PDFList(indentations: [ (pre: 10.0, past: 20.0), (pre: 20.0, past: 20.0), - (pre: 40.0, past: 20.0) + (pre: 40.0, past: 20.0), ]) // By adding the item first to a list item with the dot symbol, all of them will inherit it featureList .addItem(PDFListItem(symbol: .dot) - .addItems(items.map({ item in + .addItems(items.map { item in PDFListItem(content: item) - }))) + })) document.add(list: featureList) document.add(space: 20) @@ -46,13 +45,13 @@ class ListExampleFactory: ExampleFactory { let weirdIndentationList = PDFList(indentations: [ (pre: 10.0, past: 20.0), (pre: 40.0, past: 30.0), - (pre: 20.0, past: 50.0) + (pre: 20.0, past: 50.0), ]) weirdIndentationList - .addItems(items.enumerated().map({ arg in + .addItems(items.enumerated().map { arg in PDFListItem(symbol: .numbered(value: "\(arg.offset + 1)"), content: arg.element) - })) + }) document.add(list: weirdIndentationList) return [document] diff --git a/Shared/Examples/MetadataExampleFactory.swift b/Shared/Examples/MetadataExampleFactory.swift index 5436338c..e68c622b 100644 --- a/Shared/Examples/MetadataExampleFactory.swift +++ b/Shared/Examples/MetadataExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class MetadataExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) // Set document meta data @@ -30,7 +29,7 @@ class MetadataExampleFactory: ExampleFactory { document.set(font: Font.systemFont(ofSize: 30)) document.add(text: "Nothing to see here, as it is just meta!") - + return [document] } } diff --git a/Shared/Examples/MultiSectionExampleFactory.swift b/Shared/Examples/MultiSectionExampleFactory.swift index 797f5612..789a3af3 100644 --- a/Shared/Examples/MultiSectionExampleFactory.swift +++ b/Shared/Examples/MultiSectionExampleFactory.swift @@ -8,13 +8,12 @@ import TPPDF #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif class MultiSectionExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) diff --git a/Shared/Examples/MultipleDocumentsExampleFactory.swift b/Shared/Examples/MultipleDocumentsExampleFactory.swift index 78af8440..abec44eb 100644 --- a/Shared/Examples/MultipleDocumentsExampleFactory.swift +++ b/Shared/Examples/MultipleDocumentsExampleFactory.swift @@ -10,7 +10,6 @@ import Foundation import TPPDF class MultipleDocumentsExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) document.add(text: "This is a my first document!") diff --git a/Shared/Examples/ObjectAttributesExampleFactory.swift b/Shared/Examples/ObjectAttributesExampleFactory.swift index 6f168d12..32c9fd55 100644 --- a/Shared/Examples/ObjectAttributesExampleFactory.swift +++ b/Shared/Examples/ObjectAttributesExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class ObjectAttributesExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -25,7 +24,7 @@ class ObjectAttributesExampleFactory: ExampleFactory { let veryLongLink = "This is a very long link i guess" let pattern = "Word Link Word - " + veryLongLink + " - " let count = 20 - let text = (0.. [PDFDocument] { let document = PDFDocument(format: .a4) @@ -24,13 +23,13 @@ class PaginationExampleFactory: ExampleFactory { } // Add custom pagination, starting at page 1 and excluding page 3 - document.pagination = PDFPagination(container: .footerRight, style: PDFPaginationStyle.customClosure { (page, total) -> String in - return "\(page) / \(total)" - }, range: (1, 20), hiddenPages: [3, 7], textAttributes: [ - .font: Font.boldSystemFont(ofSize: 30.0), - .foregroundColor: Color.blue + document.pagination = PDFPagination(container: .footerRight, style: PDFPaginationStyle.customClosure { page, total -> String in + "\(page) / \(total)" + }, range: (1, 20), hiddenPages: [3, 7], textAttributes: [ + .font: Font.boldSystemFont(ofSize: 30.0), + .foregroundColor: Color.blue, ]) - + return [document] } } diff --git a/Shared/Examples/TableExampleFactory.swift b/Shared/Examples/TableExampleFactory.swift index 76249a42..c87e6d66 100644 --- a/Shared/Examples/TableExampleFactory.swift +++ b/Shared/Examples/TableExampleFactory.swift @@ -7,15 +7,14 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class TableExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -25,23 +24,23 @@ class TableExampleFactory: ExampleFactory { // Tables can contain Strings, Numbers, Images or nil, in case you need an empty cell. // If you add a unknown content type, an assertion will be thrown and the rendering will stop. table.content = [ - [nil, "Name", "Image", "Description"], - [1, "Waterfall", Image(named: "Image-1.jpg")!, "Water flowing down stones."], - [2, "Forrest", Image(named: "Image-2.jpg")!, "Sunlight shining through the leafs."], - [3, "Fireworks", Image(named: "Image-3.jpg")!, "Fireworks exploding into 100.000 stars"], - [4, "Fields", Image(named: "Image-4.jpg")!, "Crops growing big and providing food."], - [1, "Waterfall", Image(named: "Image-1.jpg")!, "Water flowing down stones."], - [2, "Forrest", Image(named: "Image-2.jpg")!, "Sunlight shining through the leafs."], - [3, "Fireworks", Image(named: "Image-3.jpg")!, "Fireworks exploding into 100.000 stars"], - [4, "Fields", Image(named: "Image-4.jpg")!, "Crops growing big and providing food."], - [nil, nil, nil, "Many beautiful places"] + [nil, "Name", "Image", "Description"], + [1, "Waterfall", Image(named: "Image-1.jpg")!, "Water flowing down stones."], + [2, "Forrest", Image(named: "Image-2.jpg")!, "Sunlight shining through the leafs."], + [3, "Fireworks", Image(named: "Image-3.jpg")!, "Fireworks exploding into 100.000 stars"], + [4, "Fields", Image(named: "Image-4.jpg")!, "Crops growing big and providing food."], + [1, "Waterfall", Image(named: "Image-1.jpg")!, "Water flowing down stones."], + [2, "Forrest", Image(named: "Image-2.jpg")!, "Sunlight shining through the leafs."], + [3, "Fireworks", Image(named: "Image-3.jpg")!, "Fireworks exploding into 100.000 stars"], + [4, "Fields", Image(named: "Image-4.jpg")!, "Crops growing big and providing food."], + [nil, nil, nil, "Many beautiful places"], ] table.rows.allRowsAlignment = [.center, .left, .center, .right] // The widths of each column is proportional to the total width, set by a value between 0.0 and 1.0, representing percentage. table.widths = [ - 0.1, 0.25, 0.35, 0.3 + 0.1, 0.25, 0.35, 0.3, ] // To speed up table styling, use a default and change it @@ -52,9 +51,9 @@ class TableExampleFactory: ExampleFactory { style.footerStyle = PDFTableCellStyle( colors: ( fill: Color(red: 0.171875, - green: 0.2421875, - blue: 0.3125, - alpha: 1.0), + green: 0.2421875, + blue: 0.3125, + alpha: 1.0), text: Color.white ), borders: PDFTableCellBorders(left: PDFLineStyle(type: .full), @@ -73,7 +72,7 @@ class TableExampleFactory: ExampleFactory { table.style = style // Style each cell individually - table[1,1].style = PDFTableCellStyle(colors: (fill: Color.yellow, text: Color.black)) + table[1, 1].style = PDFTableCellStyle(colors: (fill: Color.yellow, text: Color.black)) // Set table padding and margin table.padding = 5.0 @@ -103,15 +102,15 @@ class TableExampleFactory: ExampleFactory { for i in stride(from: 3, to: 48, by: 3) { table[rows: i...(i + 2), column: 1].merge(with: PDFTableCell(content: Array(repeating: "\(i),1", count: 3).joined(separator: "\n").asTableContent, - alignment: .center)) + alignment: .center)) } for i in stride(from: 4, to: 47, by: 3) { table[rows: i...(i + 2), column: 2].merge(with: PDFTableCell(content: Array(repeating: "\(i),2", count: 3).joined(separator: "\n").asTableContent, - alignment: .center)) + alignment: .center)) } for i in stride(from: 5, to: 48, by: 3) { table[rows: i...(i + 2), column: 3].merge(with: PDFTableCell(content: Array(repeating: "\(i),3", count: 3).joined(separator: "\n").asTableContent, - alignment: .center)) + alignment: .center)) } table[rows: 0..<2, column: 2].merge() diff --git a/Shared/Examples/TableOfContentsExampleFactory.swift b/Shared/Examples/TableOfContentsExampleFactory.swift index 7bf5e896..85eaa24c 100644 --- a/Shared/Examples/TableOfContentsExampleFactory.swift +++ b/Shared/Examples/TableOfContentsExampleFactory.swift @@ -7,27 +7,32 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class TableOfContentsExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) // Define doccument wide styles - let titleStyle = document.add(style: PDFTextStyle(name: "Title", - font: Font.boldSystemFont(ofSize: 50.0), - color: Color(red: 0.171875, green: 0.2421875, blue: 0.3125, alpha: 1.0))) - let headingStyle1 = document.add(style: PDFTextStyle(name: "Heading 1", - font: Font.systemFont(ofSize: 15), - color: Color.black)) - let headingStyle2 = document.add(style: PDFTextStyle(name: "Heading 2", - font: Font.systemFont(ofSize: 10), - color: Color.black)) + let titleStyle = document.add(style: PDFTextStyle( + name: "Title", + font: Font.boldSystemFont(ofSize: 50.0), + color: Color(red: 0.171875, green: 0.2421875, blue: 0.3125, alpha: 1.0) + )) + let headingStyle1 = document.add(style: PDFTextStyle( + name: "Heading 1", + font: Font.systemFont(ofSize: 15), + color: Color.black + )) + let headingStyle2 = document.add(style: PDFTextStyle( + name: "Heading 2", + font: Font.systemFont(ofSize: 10), + color: Color.black + )) // Add a string using the title style document.add(.contentCenter, textObject: PDFSimpleText(text: "TPPDF", style: titleStyle)) @@ -69,7 +74,7 @@ class TableOfContentsExampleFactory: ExampleFactory { document.add(space: 10) document.add(text: LoremIpsum.get(words: 10)) - + return [document] } } diff --git a/Shared/Examples/TextExampleFactory.swift b/Shared/Examples/TextExampleFactory.swift index 2805e16f..fff1fc74 100644 --- a/Shared/Examples/TextExampleFactory.swift +++ b/Shared/Examples/TextExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class TextExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) @@ -29,7 +28,7 @@ class TextExampleFactory: ExampleFactory { // Create and add a subtitle as an attributed string for more customization possibilities let title = NSMutableAttributedString(string: "Create PDF documents easily", attributes: [ .font: Font.systemFont(ofSize: 18.0), - .foregroundColor: Color(red: 0.171875, green: 0.2421875, blue: 0.3125, alpha: 1.0) + .foregroundColor: Color(red: 0.171875, green: 0.2421875, blue: 0.3125, alpha: 1.0), ]) document.add(.contentCenter, attributedText: title) @@ -69,7 +68,7 @@ class TextExampleFactory: ExampleFactory { document.add(space: 300) document.add(text: "Test text here") - + return [document] } } diff --git a/Shared/Examples/TextStylesExampleFactory.swift b/Shared/Examples/TextStylesExampleFactory.swift index 4ddfa5ec..bedca750 100644 --- a/Shared/Examples/TextStylesExampleFactory.swift +++ b/Shared/Examples/TextStylesExampleFactory.swift @@ -7,14 +7,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import TPPDF class TextStylesExampleFactory: ExampleFactory { - func generateDocument() -> [PDFDocument] { let document = PDFDocument(format: .a4) diff --git a/Shared/Util/ExampleFactory.swift b/Shared/Util/ExampleFactory.swift index 3bf01818..523a64ee 100644 --- a/Shared/Util/ExampleFactory.swift +++ b/Shared/Util/ExampleFactory.swift @@ -9,7 +9,5 @@ import TPPDF protocol ExampleFactory { - func generateDocument() -> [PDFDocument] - } diff --git a/Shared/Util/LoremIpsum.swift b/Shared/Util/LoremIpsum.swift index 83513772..d8744da5 100644 --- a/Shared/Util/LoremIpsum.swift +++ b/Shared/Util/LoremIpsum.swift @@ -9,220 +9,219 @@ import Foundation class LoremIpsum { - static let text = """ -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. -Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. -At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. -Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. + Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et -""" + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et + """ static func get(words count: Int) -> String { guard count > 0 else { diff --git a/Shared/Util/TimeUtils.swift b/Shared/Util/TimeUtils.swift index 527703f3..f68fa6c7 100644 --- a/Shared/Util/TimeUtils.swift +++ b/Shared/Util/TimeUtils.swift @@ -9,7 +9,6 @@ import Foundation class TimeUtils { - /** Used for debugging execution time. Converts time interval in seconds to String. diff --git a/Source/API/Delegation/PDFGeneratorDelegate.swift b/Source/API/Delegation/PDFGeneratorDelegate.swift index 92e203c4..9edc805d 100644 --- a/Source/API/Delegation/PDFGeneratorDelegate.swift +++ b/Source/API/Delegation/PDFGeneratorDelegate.swift @@ -1,5 +1,5 @@ // -// PDFGeneratorImageDelegate.swift +// PDFGeneratorDelegate.swift // TPPDF // // Created by Chris Gonzales on 10/10/20. diff --git a/Source/API/Delegation/PDFGeneratorImageDelegate.swift b/Source/API/Delegation/PDFGeneratorImageDelegate.swift index 45322b49..0b3edfbf 100644 --- a/Source/API/Delegation/PDFGeneratorImageDelegate.swift +++ b/Source/API/Delegation/PDFGeneratorImageDelegate.swift @@ -7,12 +7,14 @@ import CoreGraphics +/// Protocol used to delegate drawing of images public protocol PDFGeneratorImageDelegate: AnyObject { + /** + * Called directly before a ``PDFImage`` is drawn into the graphics context + * + * As the `image` is a reference object, it is possible to read and manipulate the object before rendering. + * + * One use-case could be overlaying the ``PDFImage/image`` with a watermark, after it final frame is calculated. + */ func generator(willBeginDrawingImage image: PDFImage, with context: PDFContext, in frame: CGRect) } - -public extension PDFGeneratorImageDelegate { - - func generator(willBeginDrawingImage image: PDFImage, with context: PDFContext, in frame: CGRect) {} - -} diff --git a/Source/API/Document/PDFDocument.swift b/Source/API/Document/PDFDocument.swift index 2f1cedb4..a1e34f95 100644 --- a/Source/API/Document/PDFDocument.swift +++ b/Source/API/Document/PDFDocument.swift @@ -6,36 +6,29 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif + /** - The main class users interact with. - This object holds the information about the document and also all PDF objects. + * This object holds the information about the document and also all PDF objects. + * + * This is the main structure to create new documents. It is the base for the `PDFGenerator` to generate the PDF output */ public class PDFDocument: CustomStringConvertible { - // MARK: - PUBLIC VARS - /** - Holds all layout information - */ + /// Holds all layout information public var layout: PDFPageLayout - /** - Holds all document information - */ - public var info: PDFInfo = PDFInfo() + /// Holds all document information + public var info: PDFInfo = .init() - /** - Holds all pagination information - */ + /// Holds all pagination information public var pagination = PDFPagination() - /** - Holds strong references to all text styles - */ + /// Holds strong references to all text styles public var styles: [PDFTextStyle] = [] /// Configuration for document/paper background @@ -43,31 +36,27 @@ public class PDFDocument: CustomStringConvertible { // MARK: - INTERNAL VARS - /** - All objects inside the document and the container they are located in - */ - internal var objects: [PDFLocatedRenderObject] = [] + /// All objects inside the document and the container they are located in + var objects: [PDFLocatedRenderObject] = [] - /** - Group holding a template or elements which will be rendered on all pages behind the actual content - */ - internal var masterGroup: PDFGroupObject? + /// Group holding a template or elements which will be rendered on all pages behind the actual content + var masterGroup: PDFGroupObject? // MARK: - PUBLIC INITIALIZERS /** - Creates a new document with the given layout - - - parameter layout: Layout information for document + * Creates a new document with the given `layout` + * + * - Parameter layout: Layout information for document */ public init(layout: PDFPageLayout) { self.layout = layout } /** - Creates a new document with a predefined `PDFPageFormat` - - - parameter layout: Predefined page formats + * Creates a new document with a predefined `PDFPageFormat` + * + * - Parameter layout: Predefined page formats */ public init(format: PDFPageFormat) { self.layout = format.layout @@ -78,10 +67,10 @@ public class PDFDocument: CustomStringConvertible { // MARK: Layout /** - Adds a empty space in the given container, between the previous and the next element - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter space: Space distance in points + * Adds a empty space in the given container, between the previous and the next element + * + * - Parameter container: Container where the space will be set + * - Parameter space: Space distance in points */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, space: CGFloat) { objects += [(container, PDFSpaceObject(space: space))] @@ -90,11 +79,11 @@ public class PDFDocument: CustomStringConvertible { // MARK: - Lines /** - Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. - Customize by adjusting parameter `style`. - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter style: Style of line + * Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. + * Customize by adjusting parameter `style`. + * + * - Parameter container: Container where the space will be set + * - Parameter style: Style of line */ public func addLineSeparator(_ container: PDFContainer = PDFContainer.contentLeft, style: PDFLineStyle) { objects += [(container, PDFLineSeparatorObject(style: style))] @@ -103,22 +92,23 @@ public class PDFDocument: CustomStringConvertible { // MARK: Image /** - Adds an image to the given container. - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter image: Image object + * Adds an image to the given container. + * + * - Parameter container: Container where the space will be set + * - Parameter image: Image object */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, image: PDFImage) { objects += [(container, PDFImageObject(image: image))] } /** - Adds an image row to the given container. - This image row will fill the full available width between left indentation and right indentation. - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter images: Array of images, from left to right - - parameter spacing: Horizontal distance between images + * Adds an image row to the given container. + * This image row will fill the full available width between left indentation and right indentation. + * + * - Parameters: + * - container: Container where the space will be set + * - images: Array of images, from left to right + * - spacing: Horizontal distance between images */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, imagesInRow images: [PDFImage], spacing: CGFloat = 5.0) { objects += [(container, PDFImageRowObject(images: images, spacing: spacing))] @@ -127,79 +117,80 @@ public class PDFDocument: CustomStringConvertible { // MARK: Text /** - Shorthand public function to add a String text to the given container - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter images: Array of images, from left to right - - parameter spacing: Horizontal distance between images + * Shorthand public function to add a String text to the given container + * + * - Parameters: + * - container: Container where the space will be set + * - images: Array of images, from left to right + * - spacing: Horizontal distance between images */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, text: String, lineSpacing: CGFloat = 1.0) { add(container, textObject: PDFSimpleText(text: text, spacing: lineSpacing)) } /** - Adds an text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter textObject: Simple text object + * Adds an text object to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter textObject: Simple text object */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, textObject: PDFSimpleText) { objects += [(container, PDFAttributedTextObject(simpleText: textObject))] } /** - Shorthand public function to add a attributed String text to the given container - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter text: An attributed string + * Shorthand public function to add a attributed String text to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter text: An attributed string */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, attributedText: NSAttributedString) { add(container, attributedTextObject: PDFAttributedText(text: attributedText)) } /** - Adds an attributed text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` - - parameter textObject: Attributed text object + * Adds an attributed text object to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter textObject: Attributed text object */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, attributedTextObject: PDFAttributedText) { objects += [(container, PDFAttributedTextObject(attributedText: attributedTextObject))] } /** - Set font in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the font will be set, defaults to `PDFContainer.contentLeft` - - parameter font: Font of text + * Set font in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the font will be set + * - Parameter font: Font of text */ public func set(_ container: PDFContainer = PDFContainer.contentLeft, font: Font) { objects += [(container, PDFFontObject(font: font))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFContainer.contentLeft` + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset */ public func resetFont(_ container: PDFContainer = PDFContainer.contentLeft) { objects += [(container, PDFFontObject(font: Font.systemFont(ofSize: PDFConstants.defaultFontSize)))] } /** - Set text color in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the text color will be set, defaults to `PDFContainer.contentLeft` - - parameter color: Color of the text + * Set text color in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the text color will be set + * - Parameter color: Color of the text */ public func set(_ container: PDFContainer = PDFContainer.contentLeft, textColor: Color) { objects += [(container, PDFTextColorObject(color: textColor))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFContainer.contentLeft` + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset */ public func resetTextColor(_ container: PDFContainer = PDFContainer.contentLeft) { objects += [(container, PDFTextColorObject(color: Color.black))] @@ -208,7 +199,10 @@ public class PDFDocument: CustomStringConvertible { // MARK: Table /** - Adds a table object to the document in the defined container + * Adds a table object to the document in the defined container + * + * - Parameter container: Container where the table color will be added + * - Parameter color: Table to add to document */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, table: PDFTable) { objects += [(container, PDFTableObject(table: table))] @@ -217,7 +211,10 @@ public class PDFDocument: CustomStringConvertible { // MARK: List /** - Adds a list object to the document in the defined container + * Adds a list object to the document in the defined container + * + * - Parameter container: Container where the text color will be set + * - Parameter color: Color of the text */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, list: PDFList) { objects += [(container, PDFListObject(list: list))] @@ -226,7 +223,9 @@ public class PDFDocument: CustomStringConvertible { // MARK: Section /** - Adds a section object to the document + * Adds a section object to the document + * + * - Parameter section: Section */ public func add(section: PDFSection) { objects += [(.contentLeft, PDFSectionObject(section: section))] @@ -235,43 +234,46 @@ public class PDFDocument: CustomStringConvertible { // MARK: Layout /** - Change the indentation in a container, use the parameter `left` to define from which side. - - - parameter container: Container whose indentation should be changed, defaults to `PDFContainer.contentLeft` - - parameter indent: Points from the side - - parameter left: If `true` then the left side indentation is set, else the right indentation is set + * Change the indentation in a container, use the parameter `left` to define from which side. + * + * - Parameters: + * - container: Container whose indentation should be changed + * - indent: Points from the side + * - left: If `true` then the left side indentation is set, else the right indentation is set */ public func set(_ container: PDFContainer = PDFContainer.contentLeft, indent: CGFloat, left: Bool) { objects += [(container, PDFIndentationObject(indentation: indent, left: left, insideSectionColumn: false))] } /** - Change the absolute top offset in a container - - - parameter container: Container whose current absoilute offset should be changed, defaults to `PDFContainer.contentLeft` - - parameter absoluteOffset: Points from the top + * Change the absolute top offset in a container + * + * - Parameter container: Container whose current absoilute offset should be changed + * - Parameter absoluteOffset: Points from the top */ public func set(_ container: PDFContainer = PDFContainer.contentLeft, absoluteOffset: CGFloat) { objects += [(container, PDFOffsetObject(offset: absoluteOffset))] } - /** - Creates a new page - */ + /// Creates a new page by adding a page break object public func createNewPage() { objects += [(.contentLeft, PDFPageBreakObject())] } /** - Adds a style to the index + * Adds a new style to the list of known styles + * + * - Parameter style: Definition of the text style */ public func add(style: PDFTextStyle) -> PDFTextStyle { - self.styles.append(style) + styles.append(style) return style } /** - Adds a table of content + * Adds a table of content + * + * - Parameter tableOfContent: Options of the table of content */ public func add(tableOfContent: PDFTableOfContent) { objects += [(.contentLeft, PDFTableOfContentObject(list: PDFList(indentations: []), options: tableOfContent))] @@ -279,9 +281,7 @@ public class PDFDocument: CustomStringConvertible { // MARK: - Column Wrapping - /** - Starts a column section with automatic wrapping - */ + /// Starts a column section with automatic wrapping public func enable(_ container: PDFContainer = PDFContainer.contentLeft, columns: Int, widths: [CGFloat], spacings: [CGFloat]) { assert(columns > 1, "A column wrap section must have more than one column") assert(widths.count >= columns, "A colum wrap section must have at least the same amount of width values as columns") @@ -289,46 +289,56 @@ public class PDFDocument: CustomStringConvertible { objects += [(container, PDFColumnWrapSectionObject(columns: columns, widths: widths, spacings: spacings))] } - /** - Finishes a column section - */ + /// Finishes a column section public func disableColumns(_ container: PDFContainer = PDFContainer.contentLeft, addPageBreak: Bool = true) { objects += [(container, PDFColumnWrapSectionObject(isDisable: true, addPageBreak: addPageBreak))] } /** - Add a group object to the given container + * Adds a group + * + * - Parameter container: Container where the group will be added + * - Parameter group: Instance of ``PDFGroup`` to add */ public func add(_ container: PDFContainer = PDFContainer.contentLeft, group: PDFGroup) { - objects += [(container, PDFGroupObject(objects: group.objects, - allowsBreaks: group.allowsBreaks, - isFullPage: false, - backgroundColor: group.backgroundColor, - backgroundImage: group.backgroundImage, - backgroundShape: group.backgroundShape, - outline: group.outline, - padding: group.padding))] + objects += [(container, PDFGroupObject( + objects: group.objects, + allowsBreaks: group.allowsBreaks, + isFullPage: false, + backgroundColor: group.backgroundColor, + backgroundImage: group.backgroundImage, + backgroundShape: group.backgroundShape, + outline: group.outline, + padding: group.padding + ))] } /** - Replaces current master group with the given one + * Replaces current master group with the given one. + * + * See ``PDFDocument/masterGroup`` for details. + * + * - Parameter master: Instance of ``PDFMasterGroup``, */ public func set(master group: PDFMasterGroup) { - self.masterGroup = PDFGroupObject(objects: group.objects, - allowsBreaks: group.allowsBreaks, - isFullPage: group.isFullPage, - backgroundColor: group.backgroundColor, - backgroundImage: group.backgroundImage, - backgroundShape: group.backgroundShape, - outline: group.outline, - padding: group.padding) + masterGroup = PDFGroupObject( + objects: group.objects, + allowsBreaks: group.allowsBreaks, + isFullPage: group.isFullPage, + backgroundColor: group.backgroundColor, + backgroundImage: group.backgroundImage, + backgroundShape: group.backgroundShape, + outline: group.outline, + padding: group.padding + ) } /** - Adds an external document to the document + * Adds an external document to the document + * + * - Parameter doc: Instance of ``PDFExternalDocument`` */ public func add(externalDocument doc: PDFExternalDocument) { - objects += [(.none, PDFExternalDocumentObject(url: doc.url, - pages: doc.pages))] + objects += [(.none, PDFExternalDocumentObject(url: doc.url, pages: doc.pages))] } } diff --git a/Source/API/Document/PDFDocumentBackground.swift b/Source/API/Document/PDFDocumentBackground.swift index 7db54b38..3189c414 100644 --- a/Source/API/Document/PDFDocumentBackground.swift +++ b/Source/API/Document/PDFDocumentBackground.swift @@ -1,9 +1,9 @@ /// Document background configuration public struct PDFDocumentBackground { - - /// Color used to fill the background on every page. - /// - /// Defaults to `nil`, which results in a transparent background + /** + * Color used to fill the background on every page. + * + * Defaults to `nil`, which results in a transparent background + */ public var color: Color? - } diff --git a/Source/API/External/PDFExternalDocument.swift b/Source/API/External/PDFExternalDocument.swift index 018202bd..4b409360 100644 --- a/Source/API/External/PDFExternalDocument.swift +++ b/Source/API/External/PDFExternalDocument.swift @@ -7,36 +7,33 @@ import Foundation -/** - Document object used for including an external PDF document - */ +/// Document object used for including an external PDF document public class PDFExternalDocument { - - /** - Url to exteranl document. - */ + /// File URL to an external document public private(set) var url: URL /** - Array of page indicies which should be included from external documents + * Array of page indicies which should be included from external documents + * + * - Note: An empty array will be result in all pages to be included. */ public var pages: [Int] = [] /** - Creates a new instance using the given `url` to locate and the `pages` parameter to select the pages. - - - parameter url: Location of file - - parameter pages: Variadic argument of page indicies + * Creates a new instance using the given `url` to locate and the `pages` parameter to select the pages. + * + * - Parameter url: Location of file + * - Parameter pages: Variadic argument of page indicies */ public convenience init(url: URL, pages: Int...) { self.init(url: url, pages: pages) } /** - Creates a new instance using the given `url` to locate and the `pages` parameter to select the pages. - - - parameter url: Location of file - - parameter pages: Array of page indicies + * Creates a new instance using the given `url` to locate and the `pages` parameter to select the pages. + * + * - Parameter url: Location of file + * - Parameter pages: Array of page indicies */ public init(url: URL, pages: [Int]) { self.url = url diff --git a/Source/API/Graphics/PDFBezierPath+Copying.swift b/Source/API/Graphics/PDFBezierPath+Copying.swift index 9b80ada5..75561e91 100644 --- a/Source/API/Graphics/PDFBezierPath+Copying.swift +++ b/Source/API/Graphics/PDFBezierPath+Copying.swift @@ -6,22 +6,18 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ -extension PDFBezierPath: NSCopying { +// MARK: - PDFBezierPath + NSCopying - /** - TODO: Documentation - */ - public func copy(with zone: NSZone? = nil) -> Any { - let path = PDFBezierPath(ref: self.refFrame) - path.elements = self.elements +extension PDFBezierPath: NSCopying { + /// Creates a copy of this path with references to the same vertices + public func copy(with _: NSZone? = nil) -> Any { + let path = PDFBezierPath(ref: refFrame) + path.elements = elements return path } } diff --git a/Source/API/Graphics/PDFBezierPath.swift b/Source/API/Graphics/PDFBezierPath.swift index 32fdc873..73375e04 100644 --- a/Source/API/Graphics/PDFBezierPath.swift +++ b/Source/API/Graphics/PDFBezierPath.swift @@ -6,157 +6,246 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * Structure to create a bezier path, similar to ``UIKit.UIBezierPath`` + * + * A bezier path consists of a set of elements relative to a reference frame, to produce a path. + * When using the ``close`` as the last element, the path will be considered as a shape instead. + * + * **Example for a diamond shape:** + * + * let size = CGSize(width: 100, height: 100) + * let path = PDFBezierPath(ref: CGRect(origin: .zero, size: size)) + * path.move(to: PDFBezierPathVertex( + * position: CGPoint(x: size.width / 2, y: 0), + * anchor: .topCenter + * )) + * path.addLine(to: PDFBezierPathVertex( + * position: CGPoint(x: size.width, y: size.height / 2), + * anchor: .middleRight + * )) + * path.addLine(to: PDFBezierPathVertex( + * position: CGPoint(x: size.width / 2, y: size.height), + * anchor: .bottomCenter + * )) + * path.addLine(to: PDFBezierPathVertex( + * position: CGPoint(x: 0, y: size.height / 2), + * anchor: .middleLeft + * )) + * path.close() + * + * The ``PDFBezierPathVertex/anchor-swift.property`` is used to handle differences between the ``PDFBezierPath/refFrame`` */ public class PDFBezierPath: CustomStringConvertible { - - /** - TODO: Documentation - */ - internal enum ElementType { - - /** - TODO: Documentation - */ + /// Elements of the path, which are processed in order + enum ElementType { + /// See ``PDFBezierPath/move(to:)`` for details case move(point: PDFBezierPathVertex) - /** - TODO: Documentation - */ + /// See ``PDFBezierPath/addLine(to:)`` for details case line(point: PDFBezierPathVertex) - /** - TODO: Documentation - */ + /// See ``PDFBezierPath/addCurve(to:controlPoint1:controlPoint2:)`` for details case curve(endPoint: PDFBezierPathVertex, controlPoint1: PDFBezierPathVertex, controlPoint2: PDFBezierPathVertex) - /** - TODO: Documentation - */ + /// See ``PDFBezierPath/addQuadCurve(to:controlPoint:)`` for details case quadCurve(endPoint: PDFBezierPathVertex, controlPoint: PDFBezierPathVertex) - /** - TODO: Documentation - */ + /// See ``PDFBezierPath/addArc(withCenter:radius:startAngle:endAngle:clockwise:)`` for details case arc(center: PDFBezierPathVertex, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) - /** - TODO: Documentation - */ + /// See ``PDFBezierPath/close()`` for details case close } - /** - TODO: Documentation - */ - internal var refFrame: CGRect + /// Frame used as reference for vertext anchors + var refFrame: CGRect - /** - TODO: Documentation - */ - internal var elements: [ElementType] = [] + /// Elements in this path + var elements: [ElementType] = [] /** - TODO: Documentation + * Creates a new bezier path with the given reference frame. + * + * When creating a new path, the path cursor is set to the default origin at `(0,0)`. + * + * - Parameter ref: Reference frame */ public init(ref: CGRect) { self.refFrame = ref } /** - TODO: Documentation + * Moves the path’s current point to the specified location. + * + * This method implicitly ends the current subpath (if any) and sets the current point to the value in the `point` parameter. + * When ending the previous subpath, this method does not actually close the subpath. + * Therefore, the first and last points of the previous subpath are not connected to each other. + * + * For many path operations, you must call this method before issuing any commands that cause a line or curve segment to be drawn. + * + * - Parameter point: A point in the current coordinate system. */ public func move(to point: PDFBezierPathVertex) { elements.append(.move(point: point)) } /** - TODO: Documentation + * Appends a straight line to the path. + * + * This method creates a straight line segment starting at the current point and ending at the point specified by the `point` parameter. + * After adding the line segment, this method updates the current point to the value in `point`. + * You must set the path’s current point (using the ``PDFBezierPath/move(to:)`` method or through the previous creation of a line + * or curve segment) before you call this method. + * If the path is empty, this method does nothing. + * + * - Parameter point: The destination point of the line segment, specified in the current coordinate system. */ public func addLine(to point: PDFBezierPathVertex) { elements.append(.line(point: point)) } /** - TODO: Documentation + * Appends a cubic Bézier curve to the path. + * + * This method appends a cubic Bézier curve from the current point to the end point specified by the `endPoint` parameter. + * The two control points define the curvature of the segment. Figure 1 shows an approximation of a cubic Bézier curve given a + * set of initial points. + * The exact curvature of the segment involves a complex mathematical relationship between all of the points and is well documented online. + * + * You must set the path’s current point (using the ``PDFBezierPath/move(to:)`` method or through the previous creation + * of a line or curve segment) before you call this method. If the path is empty, this method does nothing. + * After adding the curve segment, this method updates the current point to the value in `point`. + * + * - Parameters: + * - endPoint: The end point of the curve. + * - controlPoint1: The first control point to use when computing the curve. + * - controlPoint2: The second control point to use when computing the curve. + */ public func addCurve(to endPoint: PDFBezierPathVertex, controlPoint1: PDFBezierPathVertex, controlPoint2: PDFBezierPathVertex) { elements.append(.curve(endPoint: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)) } /** - TODO: Documentation + * Appends a quadratic Bézier curve to the path. + * + * This method appends a quadratic Bézier curve from the current point to the end point specified by the endPoint parameter. + * The relationships between the current point, control point, and end point are what defines the actual curve. + * The exact curvature of the segment involves a complex mathematical relationship between the points and is well documented online. + * + * You must set the path’s current point (using the ``PDFBezierPath/move(to:)`` method or through the previous creation of a line + * or curve segment) before you call this method. If the path is empty, this method does nothing. + * After adding the curve segment, this method updates the current point to the value in point. + * + * See ``UIBezierPath/addQuadCurve`` for more details. + * + * - Parameter endPoint: The end point of the curve. + * - Parameter controlPoint: The control point of the curve. */ public func addQuadCurve(to endPoint: PDFBezierPathVertex, controlPoint: PDFBezierPathVertex) { elements.append(.quadCurve(endPoint: endPoint, controlPoint: controlPoint)) } /** - TODO: Documentation + * Appends an arc to the path. + * + * This method adds the specified arc beginning at the current point. + * The created arc lies on the perimeter of the specified circle. + * When drawn in the default coordinate system, the start of the circle is at the right end. + * For example, specifying a start angle of 0 radians, an end angle of π radians, and setting the `clockwise` parameter to `true` draws + * the bottom half of the circle. + * However, specifying the same start and end angles but setting the `clockwise` parameter set to false draws the top half of the circle. + * After calling this method, the current point is set to the point on the arc at the end angle of the circle. + * + * See ``UIBezierPath/addArc`` for more details. + * + * - Parameters: + * - center: Specifies the center point of the circle (in the current coordinate system) used to define the arc. + * - radius: Specifies the radius of the circle used to define the arc. + * - startAngle: Specifies the starting angle of the arc (measured in radians). + * - endAngle: Specifies the end angle of the arc (measured in radians). + * - clockwise: The direction in which to draw the arc. */ public func addArc(withCenter center: PDFBezierPathVertex, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) { elements.append(.arc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)) } - /** - TODO: Documentation - */ + /// Closes the most recent subpath. public func close() { elements.append(.close) } /** - TODO: Documentation + * Converts this path into an `UIBezierPath` / `NSBezierPath` + * + * As an instance of `PDFBezierPath` uses a reference frame for anchoring coordinates, the given parameter `frame` is used as the target frame, + * for scaling in relative values using each element's anchor + * + * - Parameter frame: Target frame for scaling this path + * + * - Returns: `UIBezierPath` for iOS or `NSBezierPath` for macOS */ - public func bezierPath(in frame: CGRect) -> BezierPath { + public func bezierPath(in frame: CGRect) -> BezierPath { // swiftlint:disable:this function_body_length let bezierPath = BezierPath() for element in elements { switch element { - case .move(let point): + case let .move(point): bezierPath.move(to: calculate(point: point, in: frame)) - case .line(let point): + case let .line(point): #if os(iOS) - bezierPath.addLine(to: calculate(point: point, in: frame)) + bezierPath.addLine(to: calculate(point: point, in: frame)) #else - bezierPath.line(to: calculate(point: point, in: frame)) + bezierPath.line(to: calculate(point: point, in: frame)) #endif - case .curve(let endPoint, let controlPoint1, let controlPoint2): + case let .curve(endPoint, controlPoint1, controlPoint2): #if os(iOS) - bezierPath.addCurve(to: calculate(point: endPoint, in: frame), - controlPoint1: calculate(point: controlPoint1, in: frame), - controlPoint2: calculate(point: controlPoint2, in: frame)) + bezierPath.addCurve( + to: calculate(point: endPoint, in: frame), + controlPoint1: calculate(point: controlPoint1, in: frame), + controlPoint2: calculate(point: controlPoint2, in: frame) + ) #else - bezierPath.curve(to: calculate(point: endPoint, in: frame), - controlPoint1: calculate(point: controlPoint1, in: frame), - controlPoint2: calculate(point: controlPoint2, in: frame)) + bezierPath.curve( + to: calculate(point: endPoint, in: frame), + controlPoint1: calculate(point: controlPoint1, in: frame), + controlPoint2: calculate(point: controlPoint2, in: frame) + ) #endif - case .quadCurve(let endPoint, let controlPoint): + case let .quadCurve(endPoint, controlPoint): #if os(iOS) - bezierPath.addQuadCurve(to: calculate(point: endPoint, in: frame), - controlPoint: calculate(point: controlPoint, in: frame)) + bezierPath.addQuadCurve( + to: calculate(point: endPoint, in: frame), + controlPoint: calculate(point: controlPoint, in: frame) + ) #else - bezierPath.quadCurve(to: calculate(point: endPoint, in: frame), - controlPoint: calculate(point: controlPoint, in: frame)) + bezierPath.quadCurve( + to: calculate(point: endPoint, in: frame), + controlPoint: calculate(point: controlPoint, in: frame) + ) #endif - case .arc(let center, let radius, let startAngle, let endAngle, let clockwise): + case let .arc(center, radius, startAngle, endAngle, clockwise): #if os(iOS) - bezierPath.addArc(withCenter: calculate(point: center, in: frame), - radius: radius, - startAngle: startAngle, - endAngle: endAngle, - clockwise: clockwise) + bezierPath.addArc( + withCenter: calculate(point: center, in: frame), + radius: radius, + startAngle: startAngle, + endAngle: endAngle, + clockwise: clockwise + ) #else - bezierPath.appendArc(withCenter: calculate(point: center, in: frame), - radius: radius, - startAngle: startAngle, - endAngle: endAngle, - clockwise: clockwise) + bezierPath.appendArc( + withCenter: calculate(point: center, in: frame), + radius: radius, + startAngle: startAngle, + endAngle: endAngle, + clockwise: clockwise + ) #endif case .close: bezierPath.close() @@ -166,16 +255,33 @@ public class PDFBezierPath: CustomStringConvertible { } /** - TODO: Documentation + * Helper function to calculate the relative position of a vertext to a target frame + * + * See ``PDFBezierPathVertex/Anchor-swift.enum`` for details for anchor behaviour. + * + * - Parameter point: Vertex in this bezier path + * - Parameter frame: Target frame used to calculate relative coordinates + * + * - Returns: Scaled coordinates relative to given `frame` */ private func calculate(point: PDFBezierPathVertex, in frame: CGRect) -> CGPoint { - let diff = CGVector(dx: calculateDiffX(point: point, in: frame), - dy: calculateDiffY(point: point, in: frame)) + let diff = CGVector( + dx: calculateDiffX(point: point, in: frame), + dy: calculateDiffY(point: point, in: frame) + ) return point.position + diff } /** - TODO: Documentation + * Helper function to calculate the relative horizontal position of a vertext to a target frame + * + * The horizontal anchors are separated into `left`, `center`, and `right`. + * See ``PDFBezierPathVertex/Anchor-swift.enum`` for details for anchor behaviour. + * + * - Parameter point: Vertex in this bezier path + * - Parameter frame: Target frame used to calculate relative coordinates + * + * - Returns: Scaled horizontal coordinates relative to given `frame` */ private func calculateDiffX(point: PDFBezierPathVertex, in frame: CGRect) -> CGFloat { switch point.anchor { @@ -189,7 +295,15 @@ public class PDFBezierPath: CustomStringConvertible { } /** - TODO: Documentation + * Helper function to calculate the relative vertical position of a vertext to a target frame + * + * The horizontal anchors are separated into `top`, `middle`, and `bottom`. + * See ``PDFBezierPathVertex/Anchor-swift.enum`` for details for anchor behaviour. + * + * - Parameter point: Vertex in this bezier path + * - Parameter frame: Target frame used to calculate relative coordinates + * + * - Returns: Scaled vertical coordinates relative to given `frame` */ private func calculateDiffY(point: PDFBezierPathVertex, in frame: CGRect) -> CGFloat { switch point.anchor { diff --git a/Source/API/Graphics/PDFBezierPathVertex.swift b/Source/API/Graphics/PDFBezierPathVertex.swift index 5d0b15fc..3e99cd78 100644 --- a/Source/API/Graphics/PDFBezierPathVertex.swift +++ b/Source/API/Graphics/PDFBezierPathVertex.swift @@ -6,78 +6,59 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ +/// A vertex in a ``PDFBezierPath`` public class PDFBezierPathVertex: CustomStringConvertible { - - /** - TODO: Documentation - */ + /// Anchor used to define the handling of scaling a ``PDFBezierPath`` public enum Anchor { - /** - TODO: Documentation - */ + /// Keep distance to top and left edges of frame case topLeft - /** - TODO: Documentation - */ + /// Keep distance to top and horizontal center edges of frame case topCenter - /** - TODO: Documentation - */ + /// Keep distance to top and right edges of frame case topRight - /** - TODO: Documentation - */ + /// Keep distance to vertical middle and left edges of frame case middleLeft - /** - TODO: Documentation - */ + /// Keep distance to center of frame case middleCenter - /** - TODO: Documentation - */ + /// Keep distance to vertical middle and right edges of frame case middleRight - /** - TODO: Documentation - */ + /// Keep distance to bottom and left edges of frame case bottomLeft - /** - TODO: Documentation - */ + /// Keep distance to bottom edge and horizontal of frame case bottomCenter - /** - TODO: Documentation - */ + /// Keep distance to bottom and right edges of frame case bottomRight } - /** - TODO: Documentation - */ + /// Position of the vertex, relative to the ``PDFBezierPath`` using this vertex. public var position: CGPoint /** - TODO: Documentation + * Anchor used modify the position during scaling + * + * See ``PDFBezierPath`` for details. */ public var anchor: Anchor /** - TODO: Documentation + * Creates a new instance of a bezier path to be used with ``PDFDynamicGeometryShape`` to render complex but dynamic shapes + * + * - Parameters: + * - position: See ``PDFBezierPathVertex/position`` + * - anchor: See ``PDFBezierPathVertex/anchor`` */ public init(position: CGPoint, anchor: Anchor) { self.position = position diff --git a/Source/API/Graphics/PDFDynamicGeometryShape.swift b/Source/API/Graphics/PDFDynamicGeometryShape.swift index c06d047a..5846b41d 100644 --- a/Source/API/Graphics/PDFDynamicGeometryShape.swift +++ b/Source/API/Graphics/PDFDynamicGeometryShape.swift @@ -6,33 +6,29 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ +/// Renders an arbitrary path into the graphics context public class PDFDynamicGeometryShape: CustomStringConvertible { - - /** - TODO: Documentation - */ + /// Path of the geometry shape public var path: PDFBezierPath - /** - TODO: Documentation - */ + /// Color used to fill the shape public var fillColor: Color = .black - /** - TODO: Documentation - */ + /// Line style used to stroke the shape public var stroke: PDFLineStyle = .none /** - TODO: Documentation + * Creates a new dynamic geometry shape + * + * - Parameters: + * - path: See ``PDFDynamicGeometryShape/path` + * - fillColor: See ``PDFDynamicGeometryShape/fillColor` + * - strolke: See ``PDFDynamicGeometryShape/stroke` */ public init(path: PDFBezierPath, fillColor: Color, stroke: PDFLineStyle) { self.path = path diff --git a/Source/API/Graphics/PDFLineStyle.swift b/Source/API/Graphics/PDFLineStyle.swift index 30cf6b57..2bb95029 100644 --- a/Source/API/Graphics/PDFLineStyle.swift +++ b/Source/API/Graphics/PDFLineStyle.swift @@ -6,43 +6,33 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - This struct defines how a line or border of a table is drawn. - */ +/// Structure defining how a line should be drawn into graphics context public struct PDFLineStyle: Hashable { - - /** - Defines the type of this line - */ + /// Type of the line public var type: PDFLineType - /** - Defines the color of this line - */ + /// Color of the line public var color: Color - /** - Defines the width of this line - */ + /// Width of the line public var width: CGFloat - /** - Defines the width of this radius (Only for rect draw, not for line) - */ + /// Defines the width of this radius (Only for rect draw, not for line) public var radius: CGFloat? /** - Initialize a table line style - - - parameter type: of Line - - parameter color: of Line - - parameter width: of Line - - parameter radius: of border + * Initialize a table line style + * + * - Parameters: + * - type: See ``PDFLineStyle/type`` + * - color: See ``PDFLineStyle/color`` + * - width: See ``PDFLineStyle/width`` + * - radius: See ``PDFLineStyle/radius`` */ public init(type: PDFLineType = .full, color: Color = .black, width: CGFloat = 0.25, radius: CGFloat? = nil) { self.type = type @@ -53,6 +43,7 @@ public struct PDFLineStyle: Hashable { // MARK: - Equatable + /// nodoc public static func == (lhs: PDFLineStyle, rhs: PDFLineStyle) -> Bool { guard lhs.type == rhs.type else { return false } guard lhs.color == rhs.color else { return false } @@ -62,6 +53,7 @@ public struct PDFLineStyle: Hashable { // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(type) hasher.combine(color) @@ -71,10 +63,9 @@ public struct PDFLineStyle: Hashable { // MARK: - Defaults -extension PDFLineStyle { - +public extension PDFLineStyle { /// Shorthand method for creating an invisible line - public static var none: PDFLineStyle { + static var none: PDFLineStyle { PDFLineStyle(type: .none, width: 0) } } diff --git a/Source/API/Graphics/PDFLineType.swift b/Source/API/Graphics/PDFLineType.swift index 05b2026d..2b830e5c 100644 --- a/Source/API/Graphics/PDFLineType.swift +++ b/Source/API/Graphics/PDFLineType.swift @@ -5,33 +5,25 @@ // Created by Philip Niedertscheider on 02/11/2017. // -/** - These types of lines are available for rendering - - - full: Line without any breaks - - dashed: Line consists out of short dashes - - dotted: Lines consists out of dots - */ +/// Different types of lines public enum PDFLineType: String { + /// No visible line + case none - /** - No visible line - */ - case none = "none" + /// Full line + case full /** - Full line + * Dashed Line + * + * Dash length and spacing is three times the line width */ - case full = "full" + case dashed /** - Line is dashed, dash length and spacing is three times the line width + * Dotted Line + * + * Dot spacing is twice the line width */ - case dashed = "dashed" - - /** - Line is dotted. Dot spacing is twice the line width - */ - case dotted = "dotted" - + case dotted } diff --git a/Source/API/Groups/PDFGroup+Objects.swift b/Source/API/Groups/PDFGroup+Objects.swift index a07db8a0..b40eebfb 100644 --- a/Source/API/Groups/PDFGroup+Objects.swift +++ b/Source/API/Groups/PDFGroup+Objects.swift @@ -6,25 +6,21 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - This extension contains all functions to modify the objects of a group - */ public extension PDFGroup { - // MARK: - PUBLIC FUNCS // MARK: - Layout /** - Adds a empty space in the given container, between the previous and the next element - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter space: Space distance in points + * Adds a empty space in the given container, between the previous and the next element + * + * - Parameter container: Container where the space will be set + * - Parameter space: Space distance in points */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, space: CGFloat) { objects += [(container, PDFSpaceObject(space: space))] @@ -33,11 +29,11 @@ public extension PDFGroup { // MARK: - Lines /** - Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. - Customize by adjusting parameter `style`. - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter style: Style of line + * Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. + * Customize by adjusting parameter `style`. + * + * - Parameter container: Container where the space will be set + * - Parameter style: Style of line */ func addLineSeparator(_ container: PDFGroupContainer = PDFGroupContainer.left, style: PDFLineStyle) { objects += [(container, PDFLineSeparatorObject(style: style))] @@ -46,22 +42,22 @@ public extension PDFGroup { // MARK: - Image /** - Adds an image to the given container. - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter image: Image object + * Adds an image to the given container. + * + * - Parameter container: Container where the space will be set + * - Parameter image: Image object */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, image: PDFImage) { objects += [(container, PDFImageObject(image: image))] } /** - Adds an image row to the given container. - This image row will fill the full available width between left indentation and right indentation. - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter images: Array of images, from left to right - - parameter spacing: Horizontal distance between images + * Adds an image row to the given container. + * This image row will fill the full available width between left indentation and right indentation. + * + * - Parameter container: Container where the space will be set + * - Parameter images: Array of images, from left to right + * - Parameter spacing: Horizontal distance between images */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, imagesInRow: [PDFImage], spacing: CGFloat = 5.0) { objects += [(container, PDFImageRowObject(images: imagesInRow, spacing: spacing))] @@ -70,79 +66,80 @@ public extension PDFGroup { // MARK: - Text /** - Shorthand function to add a String text to the given container - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter images: Array of images, from left to right - - parameter spacing: Horizontal distance between images + * Shorthand function to add a String text to the given container + * + * - Parameters: + * - container: Container where the space will be set + * - images: Array of images, from left to right + * - spacing: Horizontal distance between images */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, text: String, lineSpacing: CGFloat = 1.0) { add(container, textObject: PDFSimpleText(text: text, spacing: lineSpacing)) } /** - Adds an text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter textObject: Simple text object + * Adds an text object to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter textObject: Simple text object */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, textObject: PDFSimpleText) { objects += [(container, PDFAttributedTextObject(simpleText: textObject))] } /** - Shorthand function to add a attributed String text to the given container - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter text: An attributed string + * Shorthand function to add a attributed String text to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter text: An attributed string */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, attributedText: NSAttributedString) { add(container, attributedTextObject: PDFAttributedText(text: attributedText)) } /** - Adds an attributed text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFGroupContainer.left` - - parameter textObject: Attributed text object + * Adds an attributed text object to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter textObject: Attributed text object */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, attributedTextObject: PDFAttributedText) { objects += [(container, PDFAttributedTextObject(attributedText: attributedTextObject))] } /** - Set font in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the font will be set, defaults to `PDFGroupContainer.left` - - parameter font: Font of text + * Set font in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the font will be set + * - Parameter font: Font of text */ func set(_ container: PDFGroupContainer = PDFGroupContainer.left, font: Font) { objects += [(container, PDFFontObject(font: font))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFGroupContainer.left` + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset */ func resetFont(_ container: PDFGroupContainer = PDFGroupContainer.left) { objects += [(container, PDFFontObject(font: Font.systemFont(ofSize: PDFConstants.defaultFontSize)))] } /** - Set text color in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the text color will be set, defaults to `PDFGroupContainer.left` - - parameter color: Color of the text + * Set text color in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the text color will be set + * - Parameter color: Color of the text */ func set(_ container: PDFGroupContainer = PDFGroupContainer.left, textColor: Color) { objects += [(container, PDFTextColorObject(color: textColor))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFGroupContainer.left` + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset */ func resetTextColor(_ container: PDFGroupContainer = PDFGroupContainer.left) { objects += [(container, PDFTextColorObject(color: Color.black))] @@ -151,7 +148,10 @@ public extension PDFGroup { // MARK: - Table /** - Adds a table object to the document in the defined container + * Adds a table object to the document in the defined container + * + * - Parameter container: Container where the table will be added + * - Parameter table: An instance of ``PDFTable`` */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, table: PDFTable) { objects += [(container, PDFTableObject(table: table))] @@ -160,7 +160,10 @@ public extension PDFGroup { // MARK: - List /** - Adds a list object to the document in the defined container + * Adds a list object to the document in the defined container + * + * - Parameter container: Container where the list will be added + * - Parameter table: An instance of ``PDFList`` */ func add(_ container: PDFGroupContainer = PDFGroupContainer.left, list: PDFList) { objects += [(container, PDFListObject(list: list))] @@ -169,21 +172,22 @@ public extension PDFGroup { // MARK: - Layout /** - Change the indentation in a container, use the parameter `left` to define from which side. - - - parameter container: Container whose indentation should be changed, defaults to `PDFGroupContainer.left` - - parameter indent: Points from the side - - parameter left: If `true` then the left side indentation is set, else the right indentation is set + * Change the indentation in a container, use the parameter `left` to define from which side. + * + * - Parameters: + * - container: Container whose indentation should be changed + * - indent: Points from the side + * - left: If `true` then the left side indentation is set, else the right indentation is set */ func set(_ container: PDFGroupContainer = PDFGroupContainer.left, indentation: CGFloat, left: Bool) { objects += [(container, PDFIndentationObject(indentation: indentation, left: left, insideSectionColumn: false))] } /** - Change the absolute top offset in a container - - - parameter container: Container whose current absolute offset should be changed, defaults to `PDFGroupContainer.left` - - parameter offset: Points from the top + * Change the absolute top offset in a container + * + * - Parameter container: Container whose current absolute offset should be changed + * - Parameter offset: Points from the top */ func set(_ container: PDFGroupContainer = PDFGroupContainer.left, absoluteOffset: CGFloat) { objects += [(container, PDFOffsetObject(offset: absoluteOffset))] diff --git a/Source/API/Groups/PDFGroup.swift b/Source/API/Groups/PDFGroup.swift index b500cf3c..06a97405 100644 --- a/Source/API/Groups/PDFGroup.swift +++ b/Source/API/Groups/PDFGroup.swift @@ -6,66 +6,99 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * Object used to dynamically add multiple elements to a document, but calculate them as one. + * + * This way it is possible to add e.g. multiple ``PDFText`` elements and if the calculations require a page break, it can be disabled. + * Additionally groups allow to set either an ``UIKit.UIColor`` / ``AppKit.NSColor`` as the ``PDFGroup/backgroundColor`` + * or even create a complex ``PDFDynamicGeometryShape`` which adapts to the group frame. + * + * **Example:** + * + * The following example will create a large text with multiple indentation levels. By setting ``PDFGroup/allowsBreaks`` to `false`, + * it won't break the text, but move it to the next page in full. + * + * ```swift + * let group = PDFGroup( + * allowsBreaks: false, + * backgroundColor: .green, + * padding: UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 180) + * ) + * + * for i in 0..<10 { + * group.set(font: UIFont.systemFont(ofSize: 25)) + * group.set(indentation: 30 * CGFloat(i % 5), left: true) + * group.set(indentation: 30 * CGFloat(i % 3), left: false) + * group.add(text: "Text \(i)-\(i)-\(i)-\(i)-\(i)") + * } + * + * document.add(group: group) + * ``` + * + * See ``PDFGroupObject/draw(generator:container:in:)`` for internal implementation details */ public class PDFGroup { - // MARK: - PUBLIC VARS - /** - TODO: Documentation - */ + /// Flag to control if the group should allow page breaks inside, or if it should be moved to the next page in full. public var allowsBreaks: Bool /** - TODO: Documentation + * Filling background color in the frame of the group + * + * Will be overlayed by ``PDFGroup/backgroundImage`` and ``PDFGroup/backgroundShape`` */ public var backgroundColor: Color? /** - TODO: Documentation + * Outline style used if ``PDFGroup/backgroundColor`` is configured. + * + * Setting this value without ``PDFGroup/backgroundColor`` will not have any effect. */ - public var backgroundImage: PDFImage? + public var outline: PDFLineStyle /** - TODO: Documentation + * Filling background image in the frame of the group + * + * Will overlay ``PDFGroup/backgroundColor`` and overlayed by``PDFGroup/backgroundShape`` */ - public var backgroundShape: PDFDynamicGeometryShape? + public var backgroundImage: PDFImage? /** - TODO: Documentation + * Filling background shape in the frame of the group + * + * Will be overlay ``PDFGroup/backgroundColor`` and ``PDFGroup/backgroundImage`` */ - public var outline: PDFLineStyle + public var backgroundShape: PDFDynamicGeometryShape? /** - TODO: Documentation + * Inside padding of content to the edge + * + * Useful to add a spacing between the content and the ``PDFGroup/outline`` */ public var padding: EdgeInsets // MARK: - INTERNAL VARS - /** - All objects inside the document and the container they are located in - */ - internal var objects: [(PDFGroupContainer, PDFRenderObject)] = [] + /// All objects inside the document and the container they are located in + var objects: [(PDFGroupContainer, PDFRenderObject)] = [] // MARK: - PUBLIC INITIALIZERS - /** - TODO: Documentation - */ - public init(allowsBreaks: Bool = false, - backgroundColor: Color? = nil, - backgroundImage: PDFImage? = nil, - backgroundShape: PDFDynamicGeometryShape? = nil, - outline: PDFLineStyle = .none, - padding: EdgeInsets = .zero) { + /// Creates a new instance of `PDFGroup` with default configuration + public init( + allowsBreaks: Bool = false, + backgroundColor: Color? = nil, + backgroundImage: PDFImage? = nil, + backgroundShape: PDFDynamicGeometryShape? = nil, + outline: PDFLineStyle = .none, + padding: EdgeInsets = .zero + ) { self.allowsBreaks = allowsBreaks self.backgroundColor = backgroundColor self.backgroundImage = backgroundImage @@ -74,15 +107,15 @@ public class PDFGroup { self.padding = padding } - /** - Creates a new `PDFSectionColumn` with the same properties - */ - internal var copy: PDFGroup { - PDFGroup(allowsBreaks: self.allowsBreaks, - backgroundColor: self.backgroundColor, - backgroundImage: self.backgroundImage, - backgroundShape: self.backgroundShape, - outline: self.outline, - padding: self.padding) + /// nodoc + var copy: PDFGroup { + PDFGroup( + allowsBreaks: allowsBreaks, + backgroundColor: backgroundColor, + backgroundImage: backgroundImage, + backgroundShape: backgroundShape, + outline: outline, + padding: padding + ) } } diff --git a/Source/API/Groups/PDFGroupContainer.swift b/Source/API/Groups/PDFGroupContainer.swift index ccc14494..f0f0a1b7 100644 --- a/Source/API/Groups/PDFGroupContainer.swift +++ b/Source/API/Groups/PDFGroupContainer.swift @@ -5,32 +5,26 @@ // Created by Philip Niedertscheider on 31.05.19. // -/** - A section container defines the position of an element in a column of a given container. - */ +/// A section container defines the position of an element in a column of a given container. public enum PDFGroupContainer { - - /** - Element is in no container, only real use is as a default value - */ + /// Element is in no container, only real use is as a default value case none - /** - Container aligned to left - */ + /// Container aligned to left case left - /** - Container aligned to center - */ + /// Container aligned to center case center - /** - Container aligned to right - */ + /// Container aligned to right case right - internal init(from container: PDFContainer) { + /** + * Convenience initializer to convert a ``PDFContainer`` into a ``PDFGroupContainer`` + * + * - Parameter container: Container to convert + */ + init(from container: PDFContainer) { if container.isLeft { self = .left } else if container.isRight { @@ -41,22 +35,25 @@ public enum PDFGroupContainer { } /** - Array of all possible containers, expect `.none`. - Useful for initializing default values for each container + * Array of all possible containers, expect `.none`. + * + * Useful for initializing default values for each container */ - internal static var all: [PDFGroupContainer] { + static var all: [PDFGroupContainer] { [.left, .center, .right] } - /** - Returns the mapped `PDFContainer` - */ - internal var contentContainer: PDFContainer { + /// Returns the mapped `PDFContainer` + var contentContainer: PDFContainer { switch self { - case .left: return PDFContainer.contentLeft - case .center: return PDFContainer.contentCenter - case .right: return PDFContainer.contentRight - default: return PDFContainer.none + case .left: + return PDFContainer.contentLeft + case .center: + return PDFContainer.contentCenter + case .right: + return PDFContainer.contentRight + default: + return PDFContainer.none } } } diff --git a/Source/API/Groups/PDFMasterGroup.swift b/Source/API/Groups/PDFMasterGroup.swift index 606152b7..09221f5c 100644 --- a/Source/API/Groups/PDFMasterGroup.swift +++ b/Source/API/Groups/PDFMasterGroup.swift @@ -6,20 +6,24 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * Subclass of ``PDFGroup`` with additional properties to configure page background content + * + * Each instance of ``PDFDocument`` can have one group set as the ``PDFDocument/masterGroup` */ public class PDFMasterGroup: PDFGroup { - + /// Flag if `true`, the render frame of the group is the as large as the page allows, otherwise only as large as its content objects public var isFullPage: Bool /** - TODO: Documentation + * Creates a new master group with default values + * + * - Parameter isFullPage: See ``PDFMasterGroup/isFullPage`` for details */ public init(isFullPage: Bool = false) { self.isFullPage = isFullPage @@ -27,15 +31,19 @@ public class PDFMasterGroup: PDFGroup { } /** - TODO: Documentation + * Configures the space between the group and the edges of the page. + * + * - Parameters: + * - left: Space to left page edge + * - right: Space to right page edge + * - top: Space to top page edge + * - bottom: Space to bottom page edge */ public func setMargin(left: CGFloat? = nil, right: CGFloat? = nil, top: CGFloat? = nil, bottom: CGFloat? = nil) { objects += [(.none, PDFMarginObject(left: left, right: right, top: top, bottom: bottom))] } - /** - TODO: Documentation - */ + /// Resets the margin of the group to the margin of the ``PDFDocument/layout`` public func resetMargin() { objects += [(.none, PDFMarginObject(reset: true))] } diff --git a/Source/API/Image/PDFImage.swift b/Source/API/Image/PDFImage.swift index 05bce8c8..784aa894 100644 --- a/Source/API/Image/PDFImage.swift +++ b/Source/API/Image/PDFImage.swift @@ -6,72 +6,68 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Image element for the PDF document. Contains all information about an image, including the caption. + * Image element for the PDF document. + * + * Contains all information about an image, including the caption. */ public class PDFImage: PDFDocumentObject { - /** - The actual image + * The actual image */ public var image: Image /** - An instance of a `PDFText` subclass. - Use `PDFSimpleText` for a simple, container-based styled caption and `PDFAttributedText` for advanced styling. + * An instance of a `PDFText` subclass. + * Use `PDFSimpleText` for a simple, container-based styled caption and `PDFAttributedText` for advanced styling. */ public var caption: PDFText? - /** - The size of the image in the PDF document - */ + /// The size of the image in the PDF document public var size: CGSize - /** - Defines how the image will fit if not enough space is given - */ + /// Defines how the image will fit if not enough space is given public var sizeFit: PDFImageSizeFit /** - JPEG quality of image. - - Value ranges between 0.0 and 1.0, maximum quality equals 1.0 + * JPEG quality of image. + * + * Value ranges between 0.0 and 1.0, maximum quality equals 1.0 */ public var quality: CGFloat - /** - Options used for changing the image before drawing - */ + /// Options used for changing the image before drawing public var options: PDFImageOptions - /** - Optional corner radius, is used if the `options` are set. - */ + /// Optional corner radius, is used if the `options` are set. public var cornerRadius: CGFloat? /** - Initializer to create a PDF image element. - - - parameter image: Image which will be drawn - - parameter caption: Optional instance of a `PDFText` subclass, defaults to `nil` - - parameter size: Size of image, defaults to zero size - - parameter sizeFit: Defines how the image will fit if not enough space is given, defaults to `PDFImageSizeFit.widthHeight` - - parameter quality: JPEG quality between 0.0 and 1.0, defaults to 0.85 - - parameter options: Defines if the image will be modified before rendering - - parameter cornerRadius: Defines the radius of the corners + * Initializer to create a PDF image element. + * + * - Parameters: + * - image: Image which will be drawn + * - caption: Optional instance of a `PDFText` subclass, defaults to `nil` + * - size: Size of image, defaults to zero size + * - sizeFit: Defines how the image will fit if not enough space is given, defaults to `PDFImageSizeFit.widthHeight` + * - quality: JPEG quality between 0.0 and 1.0, defaults to 0.85 + * - options: Defines if the image will be modified before rendering + * - cornerRadius: Defines the radius of the corners */ - public init(image: Image, - caption: PDFText? = nil, - size: CGSize = .zero, - sizeFit: PDFImageSizeFit = .widthHeight, - quality: CGFloat = 0.85, - options: PDFImageOptions = [.resize, .compress], - cornerRadius: CGFloat? = nil) { + public init( + image: Image, + caption: PDFText? = nil, + size: CGSize = .zero, + sizeFit: PDFImageSizeFit = .widthHeight, + quality: CGFloat = 0.85, + options: PDFImageOptions = [.resize, .compress], + cornerRadius: CGFloat? = nil + ) { self.image = image self.caption = caption self.size = (size == .zero) ? image.size : size @@ -81,21 +77,22 @@ public class PDFImage: PDFDocumentObject { self.cornerRadius = cornerRadius } - /** - Creates a new `PDFImage` with the same properties - */ + /// Creates a new `PDFImage` with the same properties public var copy: PDFImage { - PDFImage(image: self.image, - caption: self.caption?.copy, - size: self.size, - sizeFit: self.sizeFit, - quality: self.quality, - options: self.options, - cornerRadius: self.cornerRadius) + PDFImage( + image: image, + caption: caption?.copy, + size: size, + sizeFit: sizeFit, + quality: quality, + options: options, + cornerRadius: cornerRadius + ) } // MARK: - Equatable + /// nodoc override public func isEqual(to other: PDFDocumentObject) -> Bool { guard super.isEqual(to: other) else { return false @@ -103,25 +100,25 @@ public class PDFImage: PDFDocumentObject { guard let otherImage = other as? PDFImage else { return false } - guard self.attributes == otherImage.attributes else { + guard attributes == otherImage.attributes else { return false } - guard self.tag == otherImage.tag else { + guard tag == otherImage.tag else { return false } - guard self.image == otherImage.image else { + guard image == otherImage.image else { return false } - guard self.caption == otherImage.caption else { + guard caption == otherImage.caption else { return false } - guard self.size == otherImage.size else { + guard size == otherImage.size else { return false } - guard self.sizeFit == otherImage.sizeFit else { + guard sizeFit == otherImage.sizeFit else { return false } - guard self.quality == otherImage.quality else { + guard quality == otherImage.quality else { return false } return true @@ -129,6 +126,7 @@ public class PDFImage: PDFDocumentObject { // MARK: - Hashable + /// nodoc override public func hash(into hasher: inout Hasher) { hasher.combine(image) hasher.combine(caption) diff --git a/Source/API/Image/PDFImageOptions.swift b/Source/API/Image/PDFImageOptions.swift index 8797c690..753cecdf 100644 --- a/Source/API/Image/PDFImageOptions.swift +++ b/Source/API/Image/PDFImageOptions.swift @@ -6,60 +6,48 @@ // /** - TODO: documentation + * Options used to configure the behaviour of ``PDFImage`` + * + * Multiple options can be combined by using the ``OptionSet`` operators, i.e. using the array syntax. + * + * **Example:** + * + * ```swift + * let image = PDFImage( + * options: [.resize, .compress] + * ) + * ``` */ public struct PDFImageOptions: OptionSet, Hashable { - - /** - TODO: documentation - */ + /// nodoc public let rawValue: Int - /** - TODO: documentation - */ + /// nodoc public init(rawValue: Int) { self.rawValue = rawValue } - /** - TODO: documentation - */ + /// Image will be resized to the calculated frame public static let resize = PDFImageOptions(rawValue: 1 << 0) - /** - TODO: documentation - */ + /// Image will be compressed using the value set in the property `quality` public static let compress = PDFImageOptions(rawValue: 1 << 1) - /** - TODO: documentation - */ + /// Top-left corner of image will be rounded public static let roundedTopLeft = PDFImageOptions(rawValue: 1 << 2) - /** - TODO: documentation - */ + /// Top-right corner of image will be rounded public static let roundedTopRight = PDFImageOptions(rawValue: 1 << 3) - /** - TODO: documentation - */ + /// Bottom-right corner of image will be rounded public static let roundedBottomRight = PDFImageOptions(rawValue: 1 << 4) - /** - TODO: documentation - */ + /// Bottom-left corner of image will be rounded public static let roundedBottomLeft = PDFImageOptions(rawValue: 1 << 5) - /** - TODO: documentation - */ + /// Short-hand option to round all corners public static let rounded = PDFImageOptions(rawValue: 1 << 6) - /** - TODO: documentation - */ + /// Disables all options public static let none = PDFImageOptions(rawValue: 1 << 7) - } diff --git a/Source/API/Image/PDFImageSizeFit.swift b/Source/API/Image/PDFImageSizeFit.swift index 5ab75647..0dc13131 100644 --- a/Source/API/Image/PDFImageSizeFit.swift +++ b/Source/API/Image/PDFImageSizeFit.swift @@ -5,24 +5,14 @@ // Created by Philip Niedertscheider on 02/11/2017. // -/** - Constants defining scaling behaviour of an image, if not enough space to render full size is given. - */ +/// Constants defining scaling behaviour of an image, if not enough space to render full size is given. public enum PDFImageSizeFit { - - /** - TODO: documentation - */ + /// Scale the image to fit the available width, while keeping the aspect ratio case width - /** - TODO: documentation - */ + /// Scale the image to fit the available height, while keeping the aspect ratio case height - /** - TODO: documentation - */ + /// Scale the image to fit the available width or height, while keeping the aspect ratio case widthHeight - } diff --git a/Source/API/Layout/PDFContainer.swift b/Source/API/Layout/PDFContainer.swift index c4b4f95e..15591b19 100644 --- a/Source/API/Layout/PDFContainer.swift +++ b/Source/API/Layout/PDFContainer.swift @@ -6,67 +6,44 @@ // /** - A container defines the position of an element in the page. - - Generally a document is vertically split up into a header, a content and a footer area. - Also each part is horizontally split up into a left, a center and a right area. + * A container defines the position of an element in the page. + * + * Generally a document is vertically split up into a header, a content and a footer area. + * Also each part is horizontally split up into a left, a center and a right area. */ public enum PDFContainer: CaseIterable { - - /** - Element is in no container, only real use is as a default value - */ + /// Element is in no container, only real use is as a default value case none - /** - Container at the top left - */ + /// Container at the top left case headerLeft - /** - Container at the top center - */ + /// Container at the top center case headerCenter - /** - Container at the top right - */ + /// Container at the top right case headerRight - /** - Container in the center, aligned to left - */ + /// Container in the center, aligned to left case contentLeft - /** - Container in the center, aligned to center - */ + /// Container in the center, aligned to center case contentCenter - /** - Container in the center, aligned to right - */ + /// Container in the center, aligned to right case contentRight - /** - Container at the bottom left - */ + /// Container at the bottom left case footerLeft - /** - Container at the bottom center - */ + /// Container at the bottom center case footerCenter - /** - Container at the bottom right - */ + /// Container at the bottom right case footerRight - /** - Checks if this container is in the header area - */ - internal var isHeader: Bool { + /// Checks if this container is in the header area + var isHeader: Bool { switch self { case .headerLeft, .headerCenter, .headerRight: return true @@ -75,10 +52,8 @@ public enum PDFContainer: CaseIterable { } } - /** - Checks if this container is in the footer area - */ - internal var isFooter: Bool { + /// Checks if this container is in the footer area + var isFooter: Bool { switch self { case .footerLeft, .footerCenter, .footerRight: return true @@ -87,17 +62,13 @@ public enum PDFContainer: CaseIterable { } } - /** - Checks if this container is neither in header nor in footer, therefore in the center area - */ - internal var isCenter: Bool { + /// Checks if this container is neither in header nor in footer, therefore in the vertical center area + var isCenter: Bool { !isHeader && !isFooter } - /** - Checks if this container is on the left side - */ - internal var isLeft: Bool { + /// Checks if this container is on the left side of the page + var isLeft: Bool { switch self { case .headerLeft, .contentLeft, .footerLeft: return true @@ -106,10 +77,8 @@ public enum PDFContainer: CaseIterable { } } - /** - Checks if this container is on the right side - */ - internal var isRight: Bool { + /// Checks if this container is on the right side of the page + var isRight: Bool { switch self { case .headerRight, .contentRight, .footerRight: return true @@ -119,10 +88,11 @@ public enum PDFContainer: CaseIterable { } /** - Array of all possible containers, expect `.none`. - Useful for initializing default values for each container + * Array of all possible containers, except ``PDFContainer/none``. + * + * Useful for initializing default values for each container */ - internal static var all: [PDFContainer] { + static var all: [PDFContainer] { [ .headerLeft, .headerCenter, .headerRight, .contentLeft, .contentCenter, .contentRight, diff --git a/Source/API/Layout/PDFPageLayout.swift b/Source/API/Layout/PDFPageLayout.swift index 02ff8b95..f5f2c194 100644 --- a/Source/API/Layout/PDFPageLayout.swift +++ b/Source/API/Layout/PDFPageLayout.swift @@ -6,51 +6,51 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Contains all relevant layout informations of a pdf document - */ +/// Contains all relevant layout informations of a pdf document public struct PDFPageLayout { - // MARK: - PUBLIC VARS - /** - Size of each page - */ - public var size: CGSize = CGSize.zero + /// Size of each page + public var size: CGSize = .zero /** - Margins of each page. - - `header`: Top inset of page - `footer`: Bottom inset of page - `left`: Left inset of page - `right`: Right inset of page + * Margins of each page. + * + * `header`: Top inset of page + * `footer`: Bottom inset of page + * `left`: Left inset of page + * `right`: Right inset of page */ public var margin: EdgeInsets = .zero /** - Spaces between header, content and footer. - - `header`: Space between header and content - `footer`: Space between content and footer + * Spaces between header, content and footer. + * + * `header`: Space between header and content + * `footer`: Space between content and footer */ public var space: (header: CGFloat, footer: CGFloat) // MARK: - PUBLIC FUNCTIONS /** - Creates a new layout object using the given parameters. - - - Parameter size: Size of the page - - Parameter margin: Edge margin insets - - Parameter space: Vertical spacing between header, footer and content + * Creates a new layout object using the given parameters. + * + * - Parameters: + * - size: See ``PDFPageLayout/size`` for details + * - margin: See ``PDFPageLayout/margin`` for details + * - space: See ``PDFPageLayout/space`` for details */ - public init(size: CGSize = .zero, margin: EdgeInsets = .zero, space: (header: CGFloat, footer: CGFloat) = (0, 0)) { + public init( + size: CGSize = .zero, + margin: EdgeInsets = .zero, + space: (header: CGFloat, footer: CGFloat) = (0, 0) + ) { self.size = size self.margin = margin self.space = space @@ -58,23 +58,17 @@ public struct PDFPageLayout { // MARK: - INTERNAL COMPUTED VARS - /** - Returns a `CGRect` with a origin at zero and the `size` of the layout. - */ + /// Returns a `CGRect` with a origin at zero and the `size` of the layout. public var bounds: CGRect { CGRect(origin: .zero, size: size) } - /** - Shorthand access to layout width - */ + /// Shorthand access to layout width public var width: CGFloat { size.width } - /** - Shorthand access to layout height - */ + /// Shorthand access to layout height public var height: CGFloat { size.height } diff --git a/Source/API/List/PDFList.swift b/Source/API/List/PDFList.swift index 384e812d..bc6f0d88 100644 --- a/Source/API/List/PDFList.swift +++ b/Source/API/List/PDFList.swift @@ -1,76 +1,94 @@ // -// List.swift +// PDFList.swift // TPPDF // // Created by Philip Niedertscheider on 13/06/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * Creates a new bullet list or numbered list with multiple, indented levels. + * + * Each list item has a `pre` spacing between the page indentation to the left side of the ``PDFListItem/symbol``, and a `past` spacing at + * the right side of the symbol. + * + * ```swift + * let list = PDFList(indentations: [(pre: 0.0, past: 20.0), (pre: 20.0, past: 20.0), (pre: 40.0, past: 20.0)]) + * ``` */ public class PDFList: PDFDocumentObject { + /// Items in this list + public var items: [PDFListItem] = [] - /** - TODO: Documentation - */ - internal var items: [PDFListItem] = [] - - /** - TODO: Documentation - */ - internal var levelIndentations: [(pre: CGFloat, past: CGFloat)] = [] + /// Spacing before and after the symbol for each nesting level + public var levelIndentations: [(pre: CGFloat, past: CGFloat)] = [] /** - TODO: Documentation + * Creates a new list + * + * - Parameter indentations: Spacing before and after the symbol for each nesting level. + * If not enough indentation levels are provided, the default value `0` will be used for `pre` and `past`. */ public init(indentations: [(pre: CGFloat, past: CGFloat)]) { self.levelIndentations = indentations } /** - TODO: Documentation + * Adds the given `item` to this list + * + * - Parameter item: Item to add + * + * - Returns: Reference to this instance, useful for chaining */ @discardableResult public func addItem(_ item: PDFListItem) -> PDFList { - self.items.append(item) - + items.append(item) return self } /** - TODO: Documentation + * Appends the given `items` to this list + * + * - Parameter items: Items to append + * + * - Returns: Reference to this instance, useful for chaining */ @discardableResult public func addItems(_ items: [PDFListItem]) -> PDFList { self.items += items - return self } - /** - TODO: Documentation - */ + /// Count of items in this list public var count: Int { items.count } /** - TODO: Documentation + * Converts the added instances of ``PDFListItem`` from a nested structure into an array of tuples + * + * - Returns: Array of tuples with `level`, `text` and `symbol` for each item */ public func flatted() -> [(level: Int, text: String, symbol: PDFListItemSymbol)] { var result: [(level: Int, text: String, symbol: PDFListItemSymbol)] = [] - for (idx, item) in self.items.enumerated() { + for (idx, item) in items.enumerated() { result += flatItem(item: item, level: 0, index: idx) } return result } /** - TODO: Documentation + * Converts the added instances of ``PDFListItem`` from a nested structure into an array of tuples. + * + * - Parameters: + * - item: Instance of ``PDFListItem`` to map recursively + * - level: Current nesting level, increased during recursive calls + * - index: Index in the current level, used with ``PDFListItemSymbol/numbered(value:)`` + * + * - Returns: Array of tuples with `level`, `text` and `symbol` for each item */ private func flatItem(item: PDFListItem, level: Int, index: Int) -> [(level: Int, text: String, symbol: PDFListItemSymbol)] { var result: [(level: Int, text: String, symbol: PDFListItemSymbol)] = [] @@ -97,27 +115,23 @@ public class PDFList: PDFDocumentObject { return result } - internal func clear() { - self.items = [] + /// Removes all items from this list + func clear() { + items = [] } - /** - TODO: Documentation - */ - internal var copy: PDFList { - let list = PDFList(indentations: self.levelIndentations) + // MARK: - Copying + + /// nodoc + var copy: PDFList { + let list = PDFList(indentations: levelIndentations) list.items = items.map(\.copy) return list } // MARK: - Equatable - /// Compares two instances of `PDFList` for equality - /// - /// - Parameters: - /// - lhs: One instance of `PDFList` - /// - rhs: Another instance of `PDFList` - /// - Returns: `true`, if `levelIndentations` and `items` equal; otherwise `false` + /// nodoc override public func isEqual(to other: PDFDocumentObject) -> Bool { guard super.isEqual(to: other) else { return false @@ -125,16 +139,16 @@ public class PDFList: PDFDocumentObject { guard let otherList = other as? PDFList else { return false } - guard self.levelIndentations.count == otherList.levelIndentations.count else { + guard levelIndentations.count == otherList.levelIndentations.count else { return false } - for (idx, indentation) in self.levelIndentations.enumerated() where otherList.levelIndentations[idx] != indentation { + for (idx, indentation) in levelIndentations.enumerated() where otherList.levelIndentations[idx] != indentation { return false } - guard self.items.count == otherList.items.count else { + guard items.count == otherList.items.count else { return false } - for (idx, item) in self.items.enumerated() where otherList.items[idx] != item { + for (idx, item) in items.enumerated() where otherList.items[idx] != item { return false } return true @@ -142,6 +156,7 @@ public class PDFList: PDFDocumentObject { // MARK: - Hashable + /// nodoc override public func hash(into hasher: inout Hasher) { super.hash(into: &hasher) for (pre, post) in levelIndentations { @@ -152,15 +167,19 @@ public class PDFList: PDFDocumentObject { } } -extension PDFList: CustomDebugStringConvertible { +// MARK: CustomDebugStringConvertible +extension PDFList: CustomDebugStringConvertible { + /// nodoc public var debugDescription: String { "PDFList(levels: \(levelIndentations.debugDescription), items: \(items.debugDescription))" } } -extension PDFList: CustomStringConvertible { +// MARK: CustomStringConvertible +extension PDFList: CustomStringConvertible { + /// nodoc public var description: String { "PDFList(levels: \(levelIndentations), items: \(items))" } diff --git a/Source/API/List/PDFListItem.swift b/Source/API/List/PDFListItem.swift index 1933f725..2572c82b 100644 --- a/Source/API/List/PDFListItem.swift +++ b/Source/API/List/PDFListItem.swift @@ -6,40 +6,86 @@ // /** - TODO: documentation + * An item used in a ``PDFList`` + * + * By configuring the ``PDFListItem/symbol`` it is possible to mix the symbols used by list items. + * + * ```swift + * let document = PDFDocument(format: .a4) + * + * let items = [ + * "Simple text drawing", + * "Advanced text drawing using AttributedString", + * "Multi-layer rendering by simply setting the offset", + * "Fully calculated content sizing", + * "Automatic page wrapping", + * "Customizable pagination", + * "Fully editable header and footer", + * "Simple image positioning and rendering", + * "Image captions" + * ] + * + * // Simple bullet point list + * let featureList = PDFList(indentations: [ + * (pre: 10.0, past: 20.0), + * (pre: 20.0, past: 20.0), + * (pre: 40.0, past: 20.0) + * ]) + * + * // By adding the item first to a list item with the dot symbol, all of them will inherit it + * featureList + * .addItem(PDFListItem(symbol: .dot) + * .addItems(items.map { PDFListItem(content: $0) }) + * document.add(list: featureList) + * + * document.add(space: 20) + * + * // Numbered list with unusual indentation + * let weirdIndentationList = PDFList(indentations: [ + * (pre: 10.0, past: 20.0), + * (pre: 40.0, past: 30.0), + * (pre: 20.0, past: 50.0) + * ]) + * + * weirdIndentationList.addItems(items.enumerated().map { arg in + * PDFListItem(symbol: .numbered(value: "\(arg.offset + 1)"), content: arg.element) + * }) + * document.add(list: weirdIndentationList) + * ``` */ public class PDFListItem: PDFDocumentObject { - - /** - TODO: documentation - */ + /// Weak reference to the parent list item, used to implement the list symbol ``PDFListItemSymbol/inherit`` public weak var parent: PDFListItem? - /** - TODO: documentation - */ + /// Text content of this list item, calculated and rendered using ``PDFSimpleText`` public var content: String? - /** - TODO: documentation - */ + /// List of ``PDFListItem`` nested in this instance public var children: [PDFListItem]? - /** - TODO: documentation - */ + /// Symbol used for this list item public var symbol: PDFListItemSymbol /** - TODO: documentation + * Creates a new list item + * + * - Parameter symbol: See ``PDFListItem/symbol`` for details, defaults to ``PDFListItemSymbol/inherit`` + * - Parameter content: See ``PDFListItem/content``, defaults to `nil` */ - public init(symbol: PDFListItemSymbol = PDFListItemSymbol.inherit, content: String? = nil) { + public init( + symbol: PDFListItemSymbol = PDFListItemSymbol.inherit, + content: String? = nil + ) { self.symbol = symbol self.content = content } /** - TODO: documentation + * Appends the given `items` to the list of nested items + * + * - Parameter items: Items to append + * + * - Returns: Reference to this instance, useful for chaining */ @discardableResult public func addItems(_ items: [PDFListItem]) -> PDFListItem { for item in items { @@ -50,17 +96,25 @@ public class PDFListItem: PDFDocumentObject { } /** - TODO: documentation + * Adds the given `item` to the list of nested items + * + * - Parameter item: Item to add + * + * - Returns: Reference to this instance, useful for chaining */ @discardableResult public func addItem(_ item: PDFListItem) -> PDFListItem { item.parent = self - self.children = (self.children ?? []) + [item] + children = (children ?? []) + [item] return self } /** - TODO: documentation + * Sets the content of this list item + * + * - Parameter content: See ``PDFListItem/content`` for details + * + * - Returns: Reference to this instance, useful for chaining */ @discardableResult public func setContent(_ content: String) -> PDFListItem { self.content = content @@ -68,11 +122,11 @@ public class PDFListItem: PDFDocumentObject { return self } - /** - TODO: documentation - */ + // MARK: - Copying + + /// nodoc public var copy: PDFListItem { - let item = PDFListItem(symbol: self.symbol, content: self.content) + let item = PDFListItem(symbol: symbol, content: content) for child in children ?? [] { item.addItem(child.copy) } @@ -81,12 +135,7 @@ public class PDFListItem: PDFDocumentObject { // MARK: - Equatable - /// Compares two instances of `PDFListItem` for equality - /// - /// - Parameters: - /// - lhs: One instance of `PDFListItem` - /// - rhs: Another instance of `PDFListItem` - /// - Returns: `true`, if `attributes`, `tag`, `content`, `children` and `symbol` equal; otherwise `false` + /// nodoc override public func isEqual(to other: PDFDocumentObject) -> Bool { guard super.isEqual(to: other) else { return false @@ -94,13 +143,13 @@ public class PDFListItem: PDFDocumentObject { guard let otherListItem = other as? PDFListItem else { return false } - guard self.content == otherListItem.content else { + guard content == otherListItem.content else { return false } - guard self.children == otherListItem.children else { + guard children == otherListItem.children else { return false } - guard self.symbol == otherListItem.symbol else { + guard symbol == otherListItem.symbol else { return false } return true @@ -108,6 +157,7 @@ public class PDFListItem: PDFDocumentObject { // MARK: - Equatable + /// nodoc override public func hash(into hasher: inout Hasher) { super.hash(into: &hasher) hasher.combine(content) @@ -116,8 +166,10 @@ public class PDFListItem: PDFDocumentObject { } } -extension PDFListItem: CustomDebugStringConvertible { +// MARK: CustomDebugStringConvertible +extension PDFListItem: CustomDebugStringConvertible { + /// nodoc public var debugDescription: String { let content = self.content ?? "nil" let children = self.children?.debugDescription ?? "nil" @@ -125,8 +177,10 @@ extension PDFListItem: CustomDebugStringConvertible { } } -extension PDFListItem: CustomStringConvertible { +// MARK: CustomStringConvertible +extension PDFListItem: CustomStringConvertible { + /// nodoc public var description: String { let content = self.content ?? "nil" let children = self.children?.description ?? "nil" diff --git a/Source/API/List/PDFListItemSymbol.swift b/Source/API/List/PDFListItemSymbol.swift index 162819bc..240aaa38 100644 --- a/Source/API/List/PDFListItemSymbol.swift +++ b/Source/API/List/PDFListItemSymbol.swift @@ -5,67 +5,56 @@ // Created by Philip Niedertscheider on 13/06/2017. // -/** - TODO: documentation - */ +/// Symbol used by a list item in a ``PDFList`` public enum PDFListItemSymbol: RawRepresentable, Hashable { - - /** - TODO: documentation - */ + /// nodoc public typealias RawValue = String - /** - TODO: documentation - */ + /// Doesn't display a symbol before the content case none - /** - TODO: documentation - */ + /// If an item is nested and uses this symbol, it will take the same one as the parent. case inherit - /** - TODO: documentation - */ + /// Symbol is a middle-dot case dot - /** - TODO: documentation - */ + /// Symbol is a dash/minus. case dash /** - TODO: documentation + * Any string `value` must be provided, which will then be used as the symbol. + * + * The indentation value of the ``PDFList`` must be set correctly in the initializer ``PDFList/init(indentations:)``, + * as the indentation is not based on the symbol frame width. */ case custom(value: String) /** - TODO: documentation + * When the parent of multiple list items is of type `numbered`, it will then use the index as the symbol, starting with `1` and + * append a dot `.` to the number. + * + * If a `value` is provided, this will be used for the parent item, in case you want to override the value. */ case numbered(value: String?) - /** - TODO: documentation - */ + /// Returns the symbol as a string, to be calculated and rendered using ``PDFText`` public var stringValue: String { switch self { case .dot: return "\u{00B7}" case .dash: return "-" - case .numbered(let value): + case let .numbered(value): return (value ?? "?") + "." - case .custom(let value): + case let .custom(value): return value default: return "" } } - /** - TODO: documentation - */ + /// nodoc public var rawValue: String { switch self { case .none: @@ -83,9 +72,7 @@ public enum PDFListItemSymbol: RawRepresentable, Hashable { } } - /** - TODO: documentation - */ + /// nodoc public init?(rawValue: PDFListItemSymbol.RawValue) { switch rawValue { case "none": @@ -101,7 +88,7 @@ public enum PDFListItemSymbol: RawRepresentable, Hashable { if comps.count == 2 { switch comps[0] { case "numbered": - self = .numbered(value: (comps[1] == "nil" ? nil : comps[1])) + self = .numbered(value: comps[1] == "nil" ? nil : comps[1]) case "custom": self = .custom(value: comps[1]) default: @@ -115,6 +102,7 @@ public enum PDFListItemSymbol: RawRepresentable, Hashable { // MARK: - Equatable + /// nodoc public static func == (lhs: PDFListItemSymbol, rhs: PDFListItemSymbol) -> Bool { switch (lhs, rhs) { case (.none, .none), @@ -133,6 +121,7 @@ public enum PDFListItemSymbol: RawRepresentable, Hashable { // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(rawValue) } diff --git a/Source/API/Metadata/PDFInfo+Equatable.swift b/Source/API/Metadata/PDFInfo+Equatable.swift index 5a9a440c..90a9ec8a 100644 --- a/Source/API/Metadata/PDFInfo+Equatable.swift +++ b/Source/API/Metadata/PDFInfo+Equatable.swift @@ -5,19 +5,8 @@ // Created by Philip Niedertscheider on 04/11/2017. // -/** - Extends `PDFInfo` with comparison methods - */ extension PDFInfo: Equatable { - - /** - Compares two instances of `PDFInfo` for equality - - - parameter lhs: Left side object - - parameter rhs: Right side object - - - returns: `true` if all values of `lhs` equals `rhs` - */ + /// nodoc public static func == (lhs: PDFInfo, rhs: PDFInfo) -> Bool { guard lhs.title == rhs.title else { return false diff --git a/Source/API/Metadata/PDFInfo.swift b/Source/API/Metadata/PDFInfo.swift index 522e0e4b..3fac4a89 100644 --- a/Source/API/Metadata/PDFInfo.swift +++ b/Source/API/Metadata/PDFInfo.swift @@ -6,84 +6,100 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Information saved in PDF file metadata. - */ +/// Information saved in PDF file metadata public class PDFInfo { + /// Title of document + public var title: String - /** - Title of document. - */ - public var title = "Title" + /// Author of document + public var author: String - /** - Author of document. - */ - public var author = "Author" + /// Subject of document + public var subject: String - /** - Subject of document. - */ - public var subject = "Subject" + /// Keywords of document + public var keywords: [String] /** - Keywords of document. - */ - public var keywords = ["tppdf", "pdf", "generator"] - - /** - The owner password of the PDF document. - If this password is set the document is encrypted; otherwise, the document will not be encrypted. + * The owner password of the PDF document + * + * If this password is set the document is encrypted; otherwise, the document will not be encrypted. */ public var ownerPassword: String? /** - The user password of the PDF document. - If the document is encrypted, then this value will be the user password for the document. + * The user password of the PDF document + * + * If the document is encrypted, then this value will be the user password for the document. */ public var userPassword: String? - /** - Whether the document allows printing when unlocked with the user password. - */ - public var allowsPrinting = true + /// Whether the document allows printing when unlocked with the user password. + public var allowsPrinting: Bool - /** - Whether the document allows copying when unlocked with the user password. - */ - public var allowsCopying = true + /// Whether the document allows copying when unlocked with the user password. + public var allowsCopying: Bool /** - Initializer + * Creates a new object to manage the information metadata of a ``PDFDocument`` + * + * - Parameters: + * - title: See ``PDFInfo/title`` for details. + * - author: See ``PDFInfo/author`` for details. + * - subject: See ``PDFInfo/subject`` for details. + * - keywords: See ``PDFInfo/keywords`` for details. + * - ownerPassword: See ``PDFInfo/ownerPassword`` for details. + * - userPassword: See ``PDFInfo/userPassword`` for details. + * - allowsPrinting: See ``PDFInfo/allowsPrinting`` for details. + * - allowsCopying: See ``PDFInfo/allowsCopying`` for details. */ - public init() {} + public init( + title: String = "Title", + author: String = "Author", + subject: String = "Subject", + keywords: [String] = ["tppdf", "pdf", "generator"], + ownerPassword: String? = nil, + userPassword: String? = nil, + allowsPrinting: Bool = true, + allowsCopying: Bool = true + ) { + self.title = title + self.author = author + self.subject = subject + self.keywords = keywords + self.ownerPassword = ownerPassword + self.userPassword = userPassword + self.allowsPrinting = allowsPrinting + self.allowsCopying = allowsCopying + } /** - Generates a dictionary of metadata with the following information: - - - Title - - Author - - Subject - - Keywords - - Allows Printing - - Allows Copying - - Creator - - Owner Password - - User Password + * Generates a dictionary of metadata with the following information: + * + * - Title + * - Author + * - Subject + * - Keywords + * - Allows Printing + * - Allows Copying + * - Creator + * - Owner Password + * - User Password */ - internal func generate() -> [AnyHashable: Any] { + func generate() -> [AnyHashable: Any] { var documentInfo: [AnyHashable: Any] = [ kCGPDFContextTitle as String: title, kCGPDFContextAuthor as String: author, kCGPDFContextSubject as String: subject, kCGPDFContextKeywords as String: keywords, kCGPDFContextAllowsPrinting as String: allowsPrinting, - kCGPDFContextAllowsCopying as String: allowsCopying] + kCGPDFContextAllowsCopying as String: allowsCopying + ] var creator = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "TPPDF" creator += " " + (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0") @@ -100,5 +116,4 @@ public class PDFInfo { return documentInfo } - } diff --git a/Source/API/PDFGenerator+Generation.swift b/Source/API/PDFGenerator+Generation.swift index 63c5195e..fa9a03f9 100644 --- a/Source/API/PDFGenerator+Generation.swift +++ b/Source/API/PDFGenerator+Generation.swift @@ -6,82 +6,78 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Gives the generator the functionality to convert a `PDFDocument` into a `PDF` - */ -extension PDFGenerator { - +/// Extends the base structure with multiple ways of generating PDF documents from a ``PDFDocument``. +public extension PDFGenerator { // MARK: - PUBLIC FUNCS - /// nodoc - public func generateURL(filename: String) throws -> URL { - try self.generateURL(filename: filename, info: nil) + /// Convenience method for ``PDFGenerator/generate(to:info:)`` without `info` + func generateURL(filename: String) throws -> URL { + try generateURL(filename: filename, info: nil) } - /// nodoc - public func generate(to url: URL) throws { - try self.generate(to: url, info: nil) + /// Convenience method for ``PDFGenerator/generate(to:info:)`` without `info` + func generate(to url: URL) throws { + try generate(to: url, info: nil) } /** - Generates PDF data and writes it to a temporary file. - - - parameter to: URL where file should be saved. - - parameter info: PDF file information - - - throws: PDFError + * Generates PDF data and writes it to a temporary file at the given URL `to`. + * + * - Parameter to: URL where file should be saved. + * - Parameter info: PDF file information + * + * - Throws: ``PDFError`` if the calculations or rendering fails */ - public func generate(to url: URL, info: PDFInfo?) throws { + func generate(to url: URL, info: PDFInfo?) throws { let context = PDFContextGraphics.createPDFContext(url: url, bounds: document.layout.bounds, info: info ?? document.info) try generatePDFContext(context: context) PDFContextGraphics.closePDFContext(context) } - /// nodoc - public func generateData() throws -> Data { - try self.generateData(info: nil) + /// Convenience method for ``PDFGenerator/generateData(info:)`` without defining `info` + func generateData() throws -> Data { + try generateData(info: nil) } /** - Generates PDF data and returns it - - - parameter document: PDFDocument which should be converted into a PDF file. - - parameter info: Metadata Information added to file - - - returns: PDF Data - - - throws: PDFError + * Generates PDF data and returns it + * + * - Parameter info: Metadata Information added to file + * + * - Throws: ``PDFError`` if the calculations or rendering fails + * + * - Returns: PDF file data */ - public func generateData(info: PDFInfo?) throws -> Data { + func generateData(info: PDFInfo?) throws -> Data { let (data, context) = PDFContextGraphics.createPDFDataContext(bounds: document.layout.bounds, info: info ?? document.info) try generatePDFContext(context: context) PDFContextGraphics.closePDFContext(context) return data as Data } - // MARK: - INTERNAL FUNCS - /** - Generate PDF Context from PDFCommands - - - throws: PDFError + * Generate PDF Context from PDFCommands + * + * - Throws: ``PDFError`` if the calculations or rendering fails */ - public func generatePDFContext(context: PDFContext) throws { + func generatePDFContext(context: PDFContext) throws { let renderObjects = try createRenderObjects() try render(objects: renderObjects, in: context) } /** - Creates a list of container-object pairs which will be rendered. - - - returns: List of renderable objects + * Creates a list of container-object pairs which will be rendered. + * + * - Throws: ``PDFError`` if the calculations fail + * + * - Returns: List of renderable objects */ - public func createRenderObjects() throws -> [PDFLocatedRenderObject] { + func createRenderObjects() throws -> [PDFLocatedRenderObject] { layout.margin = document.layout.margin // First calculate master objects @@ -127,11 +123,21 @@ extension PDFGenerator { // Set layout margin according to document spec layout.margin = document.layout.margin - // Calculate + // Calculate the actual elements return try calculateRenderObjects(contentObjs: contentObjects, masterObj: masterObjects, progress: calculationProgress) } - internal func estimateTotalPageCount(of contentObjects: [PDFLocatedRenderObject], progress: Progress) throws -> Int { + /** + * Estimation algorithm for the total pages in the output document + * + * This method is used to calculate an over-estimate of the total page count, to reserve enough space in the layout for the necessary elements + * + * - Parameter contentObjects: List of objects with their corresponding location + * - Parameter progress: ``Foundation.Progress`` to report render and calculation progress + * + * - Throws: ``PDFError`` if the calculations fail + */ + private func estimateTotalPageCount(of contentObjects: [PDFLocatedRenderObject], progress: Progress) throws -> Int { // Only calculate render header & footer metrics if page has content. if !contentObjects.isEmpty && !(contentObjects.first?.1 is PDFExternalPageObject) { _ = try addHeaderFooterObjects() @@ -145,9 +151,11 @@ extension PDFGenerator { let (container, pdfObject) = locatedPdfObject if let tocObject = pdfObject as? PDFTableOfContentObject { // Create table of content from objects - tocObject.list = PDFGenerator.createTableOfContentList(objects: contentObjects, - styles: tocObject.options.styles, - symbol: tocObject.options.symbol) + tocObject.list = PDFGenerator.createTableOfContentList( + objects: contentObjects, + styles: tocObject.options.styles, + symbol: tocObject.options.symbol + ) } let objects = try pdfObject.calculate(generator: self, container: container) var prevObj: PDFLocatedRenderObject? @@ -192,7 +200,22 @@ extension PDFGenerator { return result } - private func calculateRenderObjects(contentObjs: [PDFLocatedRenderObject], masterObj: [PDFLocatedRenderObject], progress: Progress) throws -> [PDFLocatedRenderObject] { + /** + * Calculates the layout of given render objects in `contentObjs`, in addition to the given page master object `masterObj`, + * and returns a list of objects ready to be rendered. + * + * - Parameters: + * - contentObjs: List of render objects with their location + * - masterObj: List of render objects which should be added to every new page + * - progress: ``Foundation.Progress`` to report render and calculation progress + * + * - Throws: ``PDFError`` if the calculations fail + */ + private func calculateRenderObjects( // swiftlint:disable:this cyclomatic_complexity + contentObjs: [PDFLocatedRenderObject], + masterObj: [PDFLocatedRenderObject], + progress: Progress + ) throws -> [PDFLocatedRenderObject] { guard !contentObjs.isEmpty else { return [] } @@ -217,7 +240,7 @@ extension PDFGenerator { var prevObj: PDFLocatedRenderObject? for obj in objects { if needsPageBreak { - if !(prevObj?.1 is PDFExternalPageObject) && !(obj.1 is PDFExternalPageObject) { + if !(prevObj?.1 is PDFExternalPageObject), !(obj.1 is PDFExternalPageObject) { needsPageBreak = false result += try PDFPageBreakObject().calculate(generator: self, container: container) currentPage += 1 @@ -258,12 +281,13 @@ extension PDFGenerator { } /** - Returns a list of all header and footer objects with their corresponding container. - This list also contains the pagination object - - - throws: PDFError - - - returns: List of renderable objects + * Returns a list of all header and footer objects with their corresponding container. + * + * This list also contains the pagination object. + * + * - Throws: ``PDFError`` if calculations fail + * + * - Returns: List of renderable objects with their corresponding location */ private func addHeaderFooterObjects() throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] @@ -273,7 +297,7 @@ extension PDFGenerator { let pagination = document.pagination if pagination.container != .none { - if !pagination.hiddenPages.contains(currentPage) && currentPage >= pagination.range.start && currentPage <= pagination.range.end { + if !pagination.hiddenPages.contains(currentPage), currentPage >= pagination.range.start, currentPage <= pagination.range.end { let text = pagination.style.format(page: currentPage, total: totalPages) let attributedText = NSAttributedString(string: text, attributes: pagination.textAttributes) let textObject = PDFAttributedTextObject(attributedText: PDFAttributedText(text: attributedText)) @@ -292,7 +316,11 @@ extension PDFGenerator { } /** - TODO: Documentation + * Creates objects to visually render the borders of the header and footer areas + * + * - Throws: ``PDFError`` if the calculation fail + * + * - Returns: List of render objects with their corresponding location */ private func headerFooterDebugLines() throws -> [PDFLocatedRenderObject] { let headerFooterDebugLineStyle = PDFLineStyle(type: .dashed, color: .orange, width: 1) @@ -322,9 +350,9 @@ extension PDFGenerator { } /** - Renders a list of objects in their corresponding container - - - throws: PDFError, if rendering fails + * Renders a list of objects in their corresponding container + * + * - Throws: ``PDFError`` if the rendering fails */ internal func render(objects: [PDFLocatedRenderObject], in context: PDFContext) throws { let renderProgress = Progress.discreteProgress(totalUnitCount: Int64(objects.count)) @@ -349,9 +377,15 @@ extension PDFGenerator { } /** - Render a object in its corresponding container - - - throws: PDFError, if rendering fails + * Render a object in its corresponding container + * + * If a ``PDFGenerator/delegate`` has been configured, its `willBeginDrawing...` and `didFinishDrawing...` methods will be called for + * the respective render objects as defined here: + * + * - ``PDFImageObject``: + * - ``PDFGeneratorImageDelegate/generator(willBeginDrawingImage:with:in:)`` before drawing + * + * - Throws: ``PDFError``, if rendering fails */ internal func render(object: PDFRenderObject, in container: PDFContainer, in context: PDFContext) throws { if let imageObject = object as? PDFImageObject { @@ -363,49 +397,58 @@ extension PDFGenerator { // MARK: - INTERNAL STATIC FUNCS /** - Filters out all objects which are in the header area - - - parameter objects: List objects - - - returns: List of all header objects + * Filters out all objects which are in the header area + * + * - Parameter objects: List of ``PDFLocatedRenderObject`` + * + * - Returns: Filtered list of ``PDFLocatedRenderObject`` */ internal static func extractHeaderObjects(objects: [PDFLocatedRenderObject]) -> [PDFLocatedRenderObject] { objects.filter { $0.0.isHeader } } /** - Filters out all objects which are in the footer area - - - parameter objects: List objects - - - returns: List of all footer objects + * Filters out all objects which are in the footer area + * + * - Parameter objects: List of ``PDFLocatedRenderObject`` + * + * - Returns: Filtered list of ``PDFLocatedRenderObject`` */ internal static func extractFooterObjects(objects: [PDFLocatedRenderObject]) -> [PDFLocatedRenderObject] { objects.filter { $0.0.isFooter } } /** - Filters out all objects which are in the content area - - - parameter objects: List objects - - - returns: List of all content objects + * Filters out all objects which are in the content area + * + * - Parameter objects: List of ``PDFLocatedRenderObject`` + * + * - Returns: Filtered list of ``PDFLocatedRenderObject`` */ internal static func extractContentObjects(objects: [PDFLocatedRenderObject]) -> [PDFLocatedRenderObject] { objects.filter { !$0.0.isFooter && !$0.0.isHeader } } /** - TODO: Documentation + * Creates a tree of nested ``PDFList`` used to render the table of contents. + * + * - Parameters: + * - objects: List of render objects used as the basis to create the table of contents + * - styles: Weak references to the ``PDFTextStyle`` + * - symbol: Symbol used for the list items, see ``PDFListItem/symbol`` + * + * - Note: See documentation of ``PDFTableOfContent`` for details on the usage */ - internal static func createTableOfContentList(objects: [PDFLocatedRenderObject], - styles: [WeakPDFTextStyleRef], - symbol: PDFListItemSymbol) -> PDFList { + internal static func createTableOfContentList( + objects: [PDFLocatedRenderObject], + styles: [WeakPDFTextStyleRef], + symbol: PDFListItemSymbol + ) -> PDFList { var elements: [(Int, PDFAttributedTextObject)] = [] for (_, obj) in objects { if let textObj = obj as? PDFAttributedTextObject, - let style = textObj.simpleText?.style, - let styleIndex = styles.firstIndex(where: { $0.value === style }) { + let style = textObj.simpleText?.style, + let styleIndex = styles.firstIndex(where: { $0.value === style }) { elements.append((styleIndex, textObj)) } } diff --git a/Source/API/PDFGenerator.swift b/Source/API/PDFGenerator.swift index b250b7d9..29e3c442 100644 --- a/Source/API/PDFGenerator.swift +++ b/Source/API/PDFGenerator.swift @@ -6,93 +6,78 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Factory which converts a document into a PDF file + * Factory to convert a single `PDFDocument` into a PDF file + * + * This is one of the main classes used to interact with the framework. + * + * The `PDFGenerator` is a stateful object which should be used exactly once per generator task. */ public class PDFGenerator: PDFGeneratorProtocol, CustomStringConvertible { - // MARK: - INTERNAL VARS - /** - Document which will be converted - */ - internal var document: PDFDocument + /// Document which will be converted + var document: PDFDocument - /** - List of header and footer objects extracted from the document - */ - internal var headerFooterObjects: [PDFLocatedRenderObject] = [] + /// List of header and footer objects extracted from the document + var headerFooterObjects: [PDFLocatedRenderObject] = [] - /** - Layout which holds current state - */ - internal var layout = PDFLayout() + /// Layout which holds current state + var layout = PDFLayout() - /** - Current page which increments during preparation - */ - internal var currentPage: Int = 1 + /// Current page which increments during preparation + var currentPage: Int = 1 - /** - Total page count used for displaying in rendered PDF - */ + /// Total page count used for displaying in rendered PDF public var totalPages: Int = 1 - /** - Layout information used for columns layout - */ - internal var columnState = PDFColumnLayoutState() + /// Layout information used for columns layout + var columnState = PDFColumnLayoutState() - /** - Group holding elements which will be rendered on each page if not nil - */ - internal var masterGroup: PDFGroupObject? + /// Group holding elements which will be rendered on each page if not nil + var masterGroup: PDFGroupObject? - /** - Generator wide padding used for calculations of groups - */ - internal var currentPadding = EdgeInsets.zero + /// Generator wide padding used for calculations of groups + var currentPadding = EdgeInsets.zero - /** - Relative value tracking progress - */ + /// Relative value tracking progress public let progress = Progress.discreteProgress(totalUnitCount: 3) /// Object acts as a delegate during the generation process public var delegate: PDFGeneratorDelegate? - /** - Font of each container. - These values are used for simple text objects - */ - internal lazy var fonts: [PDFContainer: Font] = .init(uniqueKeysWithValues: PDFContainer.allCases.map({ container in - (container, Font.systemFont(ofSize: PDFConstants.defaultFontSize)) - })) + /// Enables the debugging mode, which will render additional visual information on different elements. + public var debug: Bool = false /** - Enables debugging on all generator instance + * Font of each container. + * + * These values are used for simple text objects */ - public var debug: Bool = false + lazy var fonts: [PDFContainer: Font] = .init(uniqueKeysWithValues: PDFContainer.allCases.map { container in + (container, Font.systemFont(ofSize: PDFConstants.defaultFontSize)) + }) /** - Text color of each container. - These values are used for simple text objects + * Text color of each container. + * + * These values are used for simple text objects */ - internal lazy var textColor: [PDFContainer: Color] = .init(uniqueKeysWithValues: PDFContainer.allCases.map({ container in + lazy var textColor: [PDFContainer: Color] = .init(uniqueKeysWithValues: PDFContainer.allCases.map { container in (container, Color.black) - })) + }) // MARK: - PUBLIC INITS /** - Initializes the generator with a document. - - - parameter document: The document which will be converted + * Initializes the generator with a ``PDFDocument```. + * + * - Parameter document: The document which will be used to create the PDF document file */ public init(document: PDFDocument) { self.document = document @@ -103,9 +88,11 @@ public class PDFGenerator: PDFGeneratorProtocol, CustomStringConvertible { // MARK: - INTERNAL FUNCS /** - Resets the generator + * Resets all temporary values of the generator. + * + * This is an internal method used to reset the generator between render passes. */ - internal func resetGenerator() { + func resetGenerator() { layout.reset() columnState.reset() currentPage = 1 diff --git a/Source/API/PDFGeneratorProtocol.swift b/Source/API/PDFGeneratorProtocol.swift index cb40b385..c3cef51c 100644 --- a/Source/API/PDFGeneratorProtocol.swift +++ b/Source/API/PDFGeneratorProtocol.swift @@ -7,104 +7,95 @@ import Foundation -/** - Protocol including all public methods and accessors available for generating documents - */ +/// Protocol including all public methods and accessors available for generating documents public protocol PDFGeneratorProtocol: AnyObject { - - /** - Instance of `Progress` used to track and control the multi-document generation - */ + /// Instance of ``Progress`` used to track and control the multi-document generation var progress: Progress { get } - /** - Flag to enable or disable the debug overlay - */ + /// Flag to enable or disable the debug overlay var debug: Bool { get set } /** - Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. - - Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. - - - parameter filename: Name of output file, `.pdf` will be appended if not given - - parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` - - - returns: Temporary URL to the output file - - - throws: Exception, if something went wrong + * Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. + * + * Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. + * + * - Parameter filename: Name of output file, `.pdf` will be appended if not given + * - Parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` + * + * - Returns: Temporary URL to the output file + * + * - Throws: Exception, if something went wrong */ func generateURL(filename: String, info: PDFInfo?) throws -> URL /** - Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. - - Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. - - - parameter filename: Name of output file, `.pdf` will be appended if not given - - - returns: Temporary URL to the output file - - - throws: Exception, if something went wrong + * Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. + * + * Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. + * + * - Parameter filename: Name of output file, `.pdf` will be appended if not given + * + * - Returns: Temporary URL to the output file + * + * - Throws: Exception, if something went wrong */ func generateURL(filename: String) throws -> URL /** - Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. - - - parameter target: URL of output file, - - parameter info: Instance of `PDFInfo` with meta file information - - - throws: Exception, if something went wrong + * Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. + * + * - Parameter target: URL of output file, + * - Parameter info: Instance of `PDFInfo` with meta file information + * + * - Throws: Exception, if something went wrong */ func generate(to url: URL, info: PDFInfo?) throws /** - Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. - - - parameter target: URL of output file, - - - throws: Exception, if something went wrong + * Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. + * + * - Parameter target: URL of output file, + * + * - Throws: Exception, if something went wrong */ func generate(to url: URL) throws /** - Generates and returns the PDF context data. - - - parameter info: Instance of `PDFInfo` with meta file information - - - throws: Exception, if something went wrong - - - returns:PDF data + * Generates and returns the PDF context data. + * + * - Parameter info: Instance of `PDFInfo` with meta file information + * + * - Throws: Exception, if something went wrong + * + * - Returns:PDF data */ func generateData(info: PDFInfo?) throws -> Data /** - Generates and returns the PDF context data. - - - throws: Exception, if something went wrong - - - returns:PDF data + * Generates and returns the PDF context data. + * + * - Throws: Exception, if something went wrong + * + * - Returns:PDF data */ func generateData() throws -> Data - } -extension PDFGeneratorProtocol { - +public extension PDFGeneratorProtocol { /** - Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. - - Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. - - - parameter filename: Name of output file, `.pdf` will be appended if not given - - parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` - - - returns: Temporary URL to the output file - - - throws: Exception, if something went wrong + * Creates a file in a guaranteed temporary folder with the given filename, generates the PDF context data and writes the result into the file. + * + * Keep in mind, the output file is in a temporary folder of the OS and should be persisted by your own logic. + * + * - Parameter filename: Name of output file, `.pdf` will be appended if not given + * - Parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` + * + * - Returns: Temporary URL to the output file + * + * - Throws: Exception, if something went wrong */ - public func generateURL(filename: String, info: PDFInfo?) throws -> URL { + func generateURL(filename: String, info: PDFInfo?) throws -> URL { let url = FileManager.generateTemporaryOutputURL(for: filename) try generate(to: url, info: info) return url diff --git a/Source/API/PDFMultiDocumentGenerator.swift b/Source/API/PDFMultiDocumentGenerator.swift index 352f2377..77fc801b 100644 --- a/Source/API/PDFMultiDocumentGenerator.swift +++ b/Source/API/PDFMultiDocumentGenerator.swift @@ -6,104 +6,91 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Generates a PDF from multiple `PDFDocument` by appending them. - */ +/// Generates a PDF from multiple ``PDFDocument`` by appending them. public class PDFMultiDocumentGenerator: PDFGeneratorProtocol { - - /** - Bounds of first document, set on initialization - */ + /// Bounds of first document, set on initialization private let bounds: CGRect - /** - Metadata information of first document, set on initialization - */ + /// Metadata information of first document, set on initialization private let info: PDFInfo - /** - Generator instances for each document - */ + /// Generator instances for each document private var generators: [PDFGenerator] - /** - Instance of `Progress` used to track and control the multi-document generation - */ + /// Instance of `Progress` used to track and control the multi-document generation public let progress: Progress - /** - Instances of `Progess` used to track and control each individual document generation - */ + /// Instances of `Progess` used to track and control each individual document generation public let progresses: [Progress] - /** - Flag to enable or disable the debug overlay - */ + /// Flag to enable or disable the debug overlay public var debug = false /** - Initializes a new multi-document generator for generating the giving documents. - It will use the page layout of the first document. - - The instance property `progress` is initialized to the total document count. - - - parameter documents: Array of `PDFDocument` instances, which will all be rendered into a single PDF context + * Initializes a new multi-document generator for generating the giving documents. + * + * It will use the page layout of the first document. + * + * The instance property `progress` is initialized to the total document count. + * + * - Parameter documents: Array of `PDFDocument` instances, which will all be rendered into a single PDF context */ public init(documents: [PDFDocument] = []) { assert(!documents.isEmpty, "At least one document is required!") self.generators = documents.map(PDFGenerator.init(document:)) - self.progresses = self.generators.map(\.progress) + self.progresses = generators.map(\.progress) self.bounds = documents.first?.layout.bounds ?? .zero self.info = documents.first?.info ?? PDFInfo() - progress = Progress.discreteProgress(totalUnitCount: Int64(documents.count)) + self.progress = Progress.discreteProgress(totalUnitCount: Int64(documents.count)) } /// nodoc public func generateURL(filename: String) throws -> URL { - try self.generateURL(filename: filename, info: nil) + try generateURL(filename: filename, info: nil) } /// nodoc public func generate(to target: URL) throws { - try self.generate(to: target, info: nil) + try generate(to: target, info: nil) } /** - Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. - - - parameter target: URL of output file, - - parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` - - - throws: Exception, if something went wrong - */ + * Creates a file at the given file URL, generates the PDF context data and writes the result idata nto the file. + * + * - Parameter target: URL of output file, + * - Parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` + * + * - Throws: Exception, if something went wrong + */ public func generate(to target: URL, info: PDFInfo?) throws { assert(!generators.isEmpty, "At least one document is required!") - let context = PDFContextGraphics.createPDFContext(url: target, bounds: self.bounds, info: self.info) + let context = PDFContextGraphics.createPDFContext(url: target, bounds: bounds, info: self.info) try processDocuments(context: context) PDFContextGraphics.closePDFContext(context) } + /// nodoc public func generateData() throws -> Data { - try self.generateData(info: nil) + try generateData(info: nil) } /** - Generates and returns the PDF context data. - - - parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` - - - throws: Exception, if something went wrong - - - returns:PDF data - */ + * Generates and returns the PDF context data. + * + * - Parameter info: Instance of `PDFInfo` with meta file information, defaults to default initializer of `PDFInfo` + * + * - Throws: Exception, if something went wrong + * + * - Returns: PDF data + */ public func generateData(info: PDFInfo? = nil) throws -> Data { assert(!generators.isEmpty, "At least one document is required!") @@ -115,12 +102,12 @@ public class PDFMultiDocumentGenerator: PDFGeneratorProtocol { } /** - Sequentially processes each document and draws into a PDF context. - - Make sure to call `UIGraphicsBeginPDFContextToData()` before, - and `UIGraphicsEndPDFContext` after calling this method. + * Sequentially processes each document and draws into a PDF context. + * + * Make sure to call `UIGraphicsBeginPDFContextToData()` before, + * and `UIGraphicsEndPDFContext` after calling this method. */ - internal func processDocuments(context: PDFContext) throws { + func processDocuments(context: PDFContext) throws { for generator in generators { generator.debug = debug progress.addChild(generator.progress, withPendingUnitCount: 1) diff --git a/Source/API/Page Format/PDFPageFormat+Layout.swift b/Source/API/Page Format/PDFPageFormat+Layout.swift index 9a4c6151..9ec6e403 100644 --- a/Source/API/Page Format/PDFPageFormat+Layout.swift +++ b/Source/API/Page Format/PDFPageFormat+Layout.swift @@ -1,27 +1,23 @@ // -// PDFPageFormat+Margin.swift +// PDFPageFormat+Layout.swift // TPPDF // // Created by Philip Niedertscheider on 11/08/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Extends the PDF page format with pdf layout methods - */ public extension PDFPageFormat { - - /** - Shorthand method to create a default `PDFPageLayout` based on the this formats `size`. - */ + /// Shorthand method to create a default `PDFPageLayout` based on the this formats `size`. var layout: PDFPageLayout { - PDFPageLayout(size: self.size, - margin: EdgeInsets(top: 60.0, left: 60.0, bottom: 60.0, right: 60.0), - space: (header: 15.0, footer: 15.0)) + PDFPageLayout( + size: size, + margin: EdgeInsets(top: 60.0, left: 60.0, bottom: 60.0, right: 60.0), + space: (header: 15.0, footer: 15.0) + ) } } diff --git a/Source/API/Page Format/PDFPageFormat+NameConstants.swift b/Source/API/Page Format/PDFPageFormat+NameConstants.swift index 9a8d8509..918207fe 100644 --- a/Source/API/Page Format/PDFPageFormat+NameConstants.swift +++ b/Source/API/Page Format/PDFPageFormat+NameConstants.swift @@ -1,7 +1,7 @@ #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -9,10 +9,10 @@ import AppKit Source for names: https://www.papersizes.org */ public extension PDFPageFormat { - /** - Returns the defined US names if this format is a US format. - If it is not a US format, it will check other constants for correct name + * Returns the defined US names if this format is a US format. + * + * If it is not a US format, it will check other constants for correct name */ var usName: String { switch self { @@ -32,8 +32,9 @@ public extension PDFPageFormat { } /** - Returns the defined ANSI name if this format is a ANSI format. - If it is not a ANSI format, it will check other constants for correct name + * Returns the defined ANSI name if this format is a ANSI format. + * + * If it is not a ANSI format, it will check other constants for correct name */ var ansiName: String { switch self { @@ -53,8 +54,9 @@ public extension PDFPageFormat { } /** - Returns the defined A-Series name if this format is a A-Series format. - If it is not a A-Series format, it will check other constants for correct name + * Returns the defined A-Series name if this format is a A-Series format. + * + * If it is not a A-Series format, it will check other constants for correct name */ var aName: String { switch self { @@ -86,8 +88,9 @@ public extension PDFPageFormat { } /** - Returns the defined B-Series name if this format is a B-Series format. - If it is not a B-Series format, it will check other constants for correct name + * Returns the defined B-Series name if this format is a B-Series format. + * + * If it is not a B-Series format, it will check other constants for correct name */ var bName: String { switch self { @@ -119,8 +122,9 @@ public extension PDFPageFormat { } /** - Returns the defined C-Series name if this format is a C-Series format. - If it is not a C-Series format, it will check other constants for correct name + * Returns the defined C-Series name if this format is a C-Series format. + * + * If it is not a C-Series format, it will check other constants for correct name */ var cName: String { switch self { diff --git a/Source/API/Page Format/PDFPageFormat+SizeConstants.swift b/Source/API/Page Format/PDFPageFormat+SizeConstants.swift index 68f112b1..aeba6728 100644 --- a/Source/API/Page Format/PDFPageFormat+SizeConstants.swift +++ b/Source/API/Page Format/PDFPageFormat+SizeConstants.swift @@ -1,52 +1,51 @@ // -// PDFPageFormat+Size.swift +// PDFPageFormat+SizeConstants.swift // TPPDF // // Created by Philip Niedertscheider on 11/08/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - This extension includes all size constnats defined by their corresponding standard. - */ +/// This extension includes all size constnats defined by their corresponding standard. public extension PDFPageFormat { - /** - Returns the defined US paper size if this format is a US format. - If it is not a US format, it will check other constants for correct size + * Returns the defined US paper size if this format is a US format. + * + * If it is not a US format, it will check other constants for correct size */ var usSize: CGSize { switch self { case .usHalfLetter: - return CGSize(width: 396, height: 612) // 140 x 216 mm | 5.5 x 8.5 in + return CGSize(width: 396, height: 612) // 140 x 216 mm | 5.5 x 8.5 in case .usLetter: - return CGSize(width: 612, height: 792) // 216 x 279 mm | 8.5 x 11.0 in + return CGSize(width: 612, height: 792) // 216 x 279 mm | 8.5 x 11.0 in case .usLegal: - return CGSize(width: 612, height: 1008) // 216 x 356 mm | 8.5 x 14.0 in + return CGSize(width: 612, height: 1008) // 216 x 356 mm | 8.5 x 14.0 in case .usJuniorLegal: - return CGSize(width: 360, height: 576) // 127 x 203 mm | 5.0 x 8.0 in + return CGSize(width: 360, height: 576) // 127 x 203 mm | 5.0 x 8.0 in case .usLedger: - return CGSize(width: 792, height: 1224) // 279 x 432 mm | 11.0 x 17.0 in + return CGSize(width: 792, height: 1224) // 279 x 432 mm | 11.0 x 17.0 in default: return size } } /** - Returns the defined ANSI paper size if this format is a ANSI format. - If it is not a ANSI format, it will check other constants for correct size + * Returns the defined ANSI paper size if this format is a ANSI format. + * + * If it is not a ANSI format, it will check other constants for correct size */ var ansiSize: CGSize { switch self { case .ansiA: - return CGSize(width: 612, height: 792) // 216 x 279 mm | 8.5 x 11.0 in + return CGSize(width: 612, height: 792) // 216 x 279 mm | 8.5 x 11.0 in case .ansiB: - return CGSize(width: 792, height: 1224) // 279 x 432 mm | 11.0 x 17.0 in + return CGSize(width: 792, height: 1224) // 279 x 432 mm | 11.0 x 17.0 in case .ansiC: return CGSize(width: 1224, height: 1584) // 432 x 559 mm | 17.0 x 22.0 in case .ansiD: @@ -59,8 +58,9 @@ public extension PDFPageFormat { } /** - Returns the defined A-Series paper size if this format is a A-Series format. - If it is not a A-Series format, it will check other constants for correct size + * Returns the defined A-Series paper size if this format is a A-Series format. + * + * If it is not a A-Series format, it will check other constants for correct size */ var aSize: CGSize { switch self { @@ -71,29 +71,30 @@ public extension PDFPageFormat { case .a2: return CGSize(width: 1191, height: 1684) // 420 x 594 mm | 16.5 x 23.4 in case .a3: - return CGSize(width: 842, height: 1191) // 297 x 420 mm | 11.7 x 16.5 in + return CGSize(width: 842, height: 1191) // 297 x 420 mm | 11.7 x 16.5 in case .a4: - return CGSize(width: 595, height: 842) // 210 x 297 mm | 8.3 x 11.7 in + return CGSize(width: 595, height: 842) // 210 x 297 mm | 8.3 x 11.7 in case .a5: - return CGSize(width: 420, height: 595) // 148 x 210 mm | 5.8 x 8.3 in + return CGSize(width: 420, height: 595) // 148 x 210 mm | 5.8 x 8.3 in case .a6: - return CGSize(width: 298, height: 420) // 105 x 148 mm | 4.1 x 5.8 in + return CGSize(width: 298, height: 420) // 105 x 148 mm | 4.1 x 5.8 in case .a7: - return CGSize(width: 210, height: 298) // 74 x 105 mm | 2.9 x 4.1 in + return CGSize(width: 210, height: 298) // 74 x 105 mm | 2.9 x 4.1 in case .a8: - return CGSize(width: 147, height: 210) // 52 x 74 mm | 2.0 x 2.9 in + return CGSize(width: 147, height: 210) // 52 x 74 mm | 2.0 x 2.9 in case .a9: - return CGSize(width: 105, height: 147) // 37 x 52 mm | 1.5 x 2.0 in + return CGSize(width: 105, height: 147) // 37 x 52 mm | 1.5 x 2.0 in case .a10: - return CGSize(width: 74, height: 105) // 26 x 37 mm | 1.0 x 1.5 in + return CGSize(width: 74, height: 105) // 26 x 37 mm | 1.0 x 1.5 in default: return size } } /** - Returns the defined B-Series paper size if this format is a B-Series format. - If it is not a B-Series format, it will check other constants for correct size + * Returns the defined B-Series paper size if this format is a B-Series format. + * + * If it is not a B-Series format, it will check other constants for correct size */ var bSize: CGSize { switch self { @@ -106,27 +107,28 @@ public extension PDFPageFormat { case .b3: return CGSize(width: 1001, height: 1417) // 353 x 500 mm | 13.9 x 19.7 in case .b4: - return CGSize(width: 709, height: 1001) // 250 x 353 mm | 9.8 x 13.9 in + return CGSize(width: 709, height: 1001) // 250 x 353 mm | 9.8 x 13.9 in case .b5: - return CGSize(width: 499, height: 709) // 176 x 250 mm | 6.9 x 9.8 in + return CGSize(width: 499, height: 709) // 176 x 250 mm | 6.9 x 9.8 in case .b6: - return CGSize(width: 354, height: 499) // 125 x 176 mm | 4.9 x 6.9 in + return CGSize(width: 354, height: 499) // 125 x 176 mm | 4.9 x 6.9 in case .b7: - return CGSize(width: 249, height: 354) // 88 x 125 mm | 3.5 x 4.9 in + return CGSize(width: 249, height: 354) // 88 x 125 mm | 3.5 x 4.9 in case .b8: - return CGSize(width: 176, height: 249) // 62 x 88 mm | 2.4 x 3.5 in + return CGSize(width: 176, height: 249) // 62 x 88 mm | 2.4 x 3.5 in case .b9: - return CGSize(width: 125, height: 176) // 44 x 62 mm | 1.7 x 2.4 in + return CGSize(width: 125, height: 176) // 44 x 62 mm | 1.7 x 2.4 in case .b10: - return CGSize(width: 88, height: 125) // 31 x 44 mm | 1.2 x 1.7 in + return CGSize(width: 88, height: 125) // 31 x 44 mm | 1.2 x 1.7 in default: return size } } /** - Returns the defined C-Series paper size if this format is a C-Series format. - If it is not a C-Series format, it will check other constants for correct size + * Returns the defined C-Series paper size if this format is a C-Series format. + * + * If it is not a C-Series format, it will check other constants for correct size */ var cSize: CGSize { switch self { @@ -137,21 +139,21 @@ public extension PDFPageFormat { case .c2: return CGSize(width: 1298, height: 1837) // 458 x 648 mm | 18.0 x 25.5 in case .c3: - return CGSize(width: 918, height: 1298) // 324 x 458 mm | 12.8 x 18.0 in + return CGSize(width: 918, height: 1298) // 324 x 458 mm | 12.8 x 18.0 in case .c4: - return CGSize(width: 649, height: 918) // 229 x 324 mm | 9.0 x 12.8 in + return CGSize(width: 649, height: 918) // 229 x 324 mm | 9.0 x 12.8 in case .c5: - return CGSize(width: 459, height: 649) // 162 x 229 mm | 6.4 x 9.0 in + return CGSize(width: 459, height: 649) // 162 x 229 mm | 6.4 x 9.0 in case .c6: - return CGSize(width: 323, height: 459) // 114 x 162 mm | 4.5 x 6.4 in + return CGSize(width: 323, height: 459) // 114 x 162 mm | 4.5 x 6.4 in case .c7: - return CGSize(width: 230, height: 323) // 81 x 114 mm | 3.2 x 4.5 in + return CGSize(width: 230, height: 323) // 81 x 114 mm | 3.2 x 4.5 in case .c8: - return CGSize(width: 162, height: 230) // 57 x 81 mm | 2.2 x 3.2 in + return CGSize(width: 162, height: 230) // 57 x 81 mm | 2.2 x 3.2 in case .c9: - return CGSize(width: 113, height: 162) // 40 x 57 mm | 1.6 x 2.2 in + return CGSize(width: 113, height: 162) // 40 x 57 mm | 1.6 x 2.2 in case .c10: - return CGSize(width: 79, height: 113) // 28 x 40 mm | 1.1 x 1.6 in + return CGSize(width: 79, height: 113) // 28 x 40 mm | 1.1 x 1.6 in default: return size } diff --git a/Source/API/Page Format/PDFPageFormat.swift b/Source/API/Page Format/PDFPageFormat.swift index 0aceeba0..96aea0cb 100644 --- a/Source/API/Page Format/PDFPageFormat.swift +++ b/Source/API/Page Format/PDFPageFormat.swift @@ -1,34 +1,32 @@ // -// PageFormat.swift +// PDFPageFormat.swift // TPPDF // // Created by Philip Niedertscheider on 12/08/16. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - * Source for page sizes: https://www.papersizes.org + * Standardized paper formats, commonly used around the world. + * * All sizes are calculated using 72 points/inch + * + * - SeeAlso: [Source](https://www.papersizes.org) */ public enum PDFPageFormat: String, CaseIterable { - - /** - Page formats mostly used in the USA - */ + /// Page formats mostly used in the USA case usHalfLetter = "us.half-letter", usLetter = "us.letter", usLegal = "us.legal", usJuniorLegal = "us.junior-legal", usLedger = "us.ledger" - /** - Page formats according to the American National Standards Institute - */ + /// Page formats according to the American National Standards Institute case ansiA = "ansi.a", ansiB = "ansi.b", ansiC = "ansi.c", @@ -36,56 +34,57 @@ public enum PDFPageFormat: String, CaseIterable { ansiE = "ansi.e" /** - A-Series of paper standard DIN 476 - For more detail: https://en.wikipedia.org/wiki/Paper_size#A_series + * A-Series of paper standard DIN 476 + * + * - SeeAlso: [Wikipedia/Paper Size#A Series](https://en.wikipedia.org/wiki/Paper_size#A_series) */ - case a0 = "a0", - a1 = "a1", - a2 = "a2", - a3 = "a3", - a4 = "a4", - a5 = "a5", - a6 = "a6", - a7 = "a7", - a8 = "a8", - a9 = "a9", - a10 = "a10" + case a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10 /** - B-Series is the geometric mean of the A-series - For more detail: https://en.wikipedia.org/wiki/Paper_size#B_series + * B-Series is the geometric mean of the A-series + * + * - SeeAlso: [Wikipedia/Paper Size#B Series](https://en.wikipedia.org/wiki/Paper_size#B_series) */ - case b0 = "b0", - b1 = "b1", - b2 = "b2", - b3 = "b3", - b4 = "b4", - b5 = "b5", - b6 = "b6", - b7 = "b7", - b8 = "b8", - b9 = "b9", - b10 = "b10" + case b0, + b1, + b2, + b3, + b4, + b5, + b6, + b7, + b8, + b9, + b10 /** - C-Series is ususally used for envelopes. Definition is written in ISO 269 - For more detail: https://en.wikipedia.org/wiki/Paper_size#C_series + * C-Series is ususally used for envelopes. Definition is written in ISO 269 + * + * For more detail: https://en.wikipedia.org/wiki/Paper_size#C_series */ - case c0 = "c0", - c1 = "c1", - c2 = "c2", - c3 = "c3", - c4 = "c4", - c5 = "c5", - c6 = "c6", - c7 = "c7", - c8 = "c8", - c9 = "c9", - c10 = "c10" + case c0, + c1, + c2, + c3, + c4, + c5, + c6, + c7, + c8, + c9, + c10 - /** - Size defined in constants - */ + /// Size defined in constants public var size: CGSize { switch self { case .usHalfLetter, .usLetter, .usLegal, .usJuniorLegal, .usLedger: @@ -101,16 +100,12 @@ public enum PDFPageFormat: String, CaseIterable { } } - /** - Swaps height and width to create a landscape format - */ + /// Swaps height and width to create a landscape format public var landscapeSize: CGSize { CGSize(width: size.height, height: size.width) } - /** - Name defined in constants - */ + /// Name defined in constants public var name: String { switch self { case .usHalfLetter, .usLetter, .usLegal, .usJuniorLegal, .usLedger: diff --git a/Source/API/Section/PDFSection.swift b/Source/API/Section/PDFSection.swift index f5f72fac..4b7b2135 100644 --- a/Source/API/Section/PDFSection.swift +++ b/Source/API/Section/PDFSection.swift @@ -6,50 +6,66 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * A multi-column section is a nested container. + * + * Creating the section with an amount of columns and their relative width, add objects to each column and then add the whole section to the document. + * + * When adding an object to the section column, you use the Array subscript `section.columns[0]`. + * You are able to give it an alignment as the first parameter, similar to the `PDFContainer` but only with `.left`, `.center` and `.right` + * as it is not possible to add a section to the header or footer containers. + * + * Use ``PDFDocument/enable(_:columns:widths:spacings:)``for details on how to enable multi-columns with automatic text wrapping, + * allowing to split a page into multiple columns and fill it up starting at the left. + * + * **Example:** + * ```swift + * let section = PDFSection(columnWidths: [0.3, 0.4, 0.3]) + * section.columns[0].addText(.right, text: "right") + * section.columns[1].addText(.left, text: "left") + * section.columns[2].addText(.center, text: "center") + * document.add(section: section) + * ``` + * + * **Attention:** + * + * Do not add a ``PDFSection`` multiple times to a ``PDFDocument``, as they hold some internal state, which will lead to collisions and unpredictable + * framing calculations. */ public class PDFSection: PDFDocumentObject { + /// List of section columns. + public private(set) var columns: [PDFSectionColumn] = [] - /** - List of section columns. - */ - public private(set) var columns: [PDFSectionColumn] = [] + /// Horizontal margin between columns in points. + public var columnMargin: CGFloat = 10.0 - /** - Horizontal margin between columns in points. - */ - public var columnMargin: CGFloat = 10.0 + // MARK: - PUBLIC INITIALIZERS - // MARK: - PUBLIC INITIALIZERS - - /** - Creates a new section with columns of the given relative widths. - - - parameter columnWidth: Relative column widths. Values are between 0.0 and 1.0 and should sum up to 1.0. - */ - public convenience init(columnWidths: [CGFloat]) { + /** + * Creates a new section with columns of the given relative widths. + * + * - Parameter columnWidth: Relative column widths. Values are between 0.0 and 1.0 and should sum up to 1.0. + */ + public convenience init(columnWidths: [CGFloat]) { self.init(columnWidths.map(PDFSectionColumn.init(width:))) - } - - /** - Creates a new section with the given columns. - - - parameter columns: Preconfigured section columns - */ - public init(_ columns: [PDFSectionColumn]) { - self.columns = columns - } + } /** - Creates a new `PDFSection` with the same properties + * Creates a new section with the given columns. + * + * - Parameter columns: Preconfigured section columns */ - internal var copy: PDFSection { - PDFSection(columns.map(\.copy)) - } + public init(_ columns: [PDFSectionColumn]) { + self.columns = columns + } + + /// nodoc + var copy: PDFSection { + PDFSection(columns.map(\.copy)) + } } diff --git a/Source/API/Section/PDFSectionColumn.swift b/Source/API/Section/PDFSectionColumn.swift index c6936ae4..f08ceb8e 100644 --- a/Source/API/Section/PDFSectionColumn.swift +++ b/Source/API/Section/PDFSectionColumn.swift @@ -6,61 +6,54 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ +/// A configurable column of a ``PDFSection`` public class PDFSectionColumn: PDFDocumentObject { - - // MARK: - PUBLIC VARS - - /** - Holds the relative column width. Value is between 0.0 and 1.0. - */ - public private(set) var width: CGFloat + // MARK: - PUBLIC VARS /** - Background color of this section + * Holds the relative column width. + * + * Value is between `0.0` and `1.0`. */ - public var backgroundColor: Color? + public private(set) var width: CGFloat - // MARK: - INTERNAL VARS - - /** - All objects inside the document and the container they are located in - */ - internal var objects: [(PDFSectionColumnContainer, PDFRenderObject)] = [] + /// Background color of this section + public var backgroundColor: Color? - // MARK: - PUBLIC INITIALIZERS + // MARK: - INTERNAL VARS - /** - Creates a new section column with the given relative width. + /// All objects inside the document and the container they are located in + var objects: [(PDFSectionColumnContainer, PDFRenderObject)] = [] - - parameter width: Relative column width. Value is between 0.0 and 1.0. - */ - public init(width: CGFloat) { - self.width = width - } + // MARK: - PUBLIC INITIALIZERS /** - Creates a new `PDFSectionColumn` with the same properties + * Creates a new section column with the given relative width. + * + * - Parameter width: See ``PDFSectionColumn/width`` for details */ - internal var copy: PDFSectionColumn { - PDFSectionColumn(width: self.width) - } + public init(width: CGFloat) { + self.width = width + } + + /// nodoc + var copy: PDFSectionColumn { + PDFSectionColumn(width: width) + } // MARK: - Layout /** - Adds a empty space in the given container, between the previous and the next element - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter space: Space distance in points - */ + * Adds a empty space in the given container, between the previous and the next element + * + * - Parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` + * - Parameter space: Space distance in points + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, space: CGFloat) { objects += [(container, PDFSpaceObject(space: space))] } @@ -68,12 +61,12 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Lines /** - Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. - Customize by adjusting parameter `style`. - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter style: Style of line - */ + * Adds a horizontal line spearator to the given container. The line starts at the left indentation and ends at the right indentation. + * Customize by adjusting parameter `style`. + * + * - Parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` + * - Parameter style: Style of line + */ public func addLineSeparator(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, style: PDFLineStyle) { objects += [(container, PDFLineSeparatorObject(style: style))] } @@ -81,23 +74,24 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Image /** - Adds an image to the given container. - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter image: Image object - */ + * Adds an image to the given container. + * + * - Parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` + * - Parameter image: Image object + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, image: PDFImage) { objects += [(container, PDFImageObject(image: image))] } /** - Adds an image row to the given container. - This image row will fill the full available width between left indentation and right indentation. - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter imagesInRow: Array of images, from left to right - - parameter spacing: Horizontal distance between images - */ + * Adds an image row to the given container. + * This image row will fill the full available width between left indentation and right indentation. + * + * - Parameters: + * - container: Container where the space will be set + * - images: Array of images, from left to + * - spacing: Horizontal distance between images + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, imagesInRow images: [PDFImage], spacing: CGFloat = 5.0) { objects += [(container, PDFImageRowObject(images: images, spacing: spacing))] } @@ -105,80 +99,80 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Text /** - Shorthand public function to add a String text to the given container + Shorthand public function to add a String text to the given container - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter images: Array of images, from left to right - - parameter spacing: Horizontal distance between images - */ + - Parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` + - Parameter images: Array of images, from left to right + - Parameter spacing: Horizontal distance between images + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, text: String, lineSpacing: CGFloat = 1.0) { add(container, textObject: PDFSimpleText(text: text, spacing: lineSpacing)) } /** - Adds an text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter textObject: Simple text object - */ + * Adds an text object to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter textObject: Simple text object + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, textObject: PDFSimpleText) { objects += [(container, PDFAttributedTextObject(simpleText: textObject))] } /** - Shorthand public function to add a attributed String text to the given container - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter text: An attributed string - */ + * Shorthand public function to add a attributed String text to the given container + * + * - Parameter container: Container where the space will be set + * - Parameter text: An attributed string + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, attributedText: NSAttributedString) { add(container, attributedTextObject: PDFAttributedText(text: attributedText)) } /** - Adds an attributed text object to the given container - - - parameter container: Container where the space will be set, defaults to `PDFSectionColumnContainer.left` - - parameter textObject: Attributed text object - */ + * Adds an attributed text object to the given container + * + * - Parameter container: Container where the space will be set, defaults to `PDFContainer.contentLeft` + * - Parameter textObject: Attributed text object + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, attributedTextObject: PDFAttributedText) { objects += [(container, PDFAttributedTextObject(attributedText: attributedTextObject))] } /** - Set font in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the font will be set, defaults to `PDFSectionColumnContainer.left` - - parameter font: Font of text - */ + * Set font in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the font will be set, defaults to `PDFContainer.contentLeft` + * - Parameter font: Font of text + */ public func set(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, font: Font) { objects += [(container, PDFFontObject(font: font))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFSectionColumnContainer.left` - */ + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset, defaults to `PDFContainer.contentLeft` + */ public func resetFont(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left) { objects += [(container, PDFFontObject(font: Font.systemFont(ofSize: PDFConstants.defaultFontSize)))] } /** - Set text color in given container. This text color will be used when adding a `PDFSimpleText` - - - parameter container: Container where the text color will be set, defaults to `PDFSectionColumnContainer.left` - - parameter color: Color of the text - */ + * Set text color in given container. This text color will be used when adding a `PDFSimpleText` + * + * - Parameter container: Container where the text color will be set, defaults to `PDFContainer.contentLeft` + * - Parameter color: Color of the text + */ public func set(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, textColor: Color) { objects += [(container, PDFTextColorObject(color: textColor))] } /** - Reset text color in given container to default. - - - parameter container: Container whose text color will be reset, defaults to `PDFSectionColumnContainer.left` - */ + * Reset text color in given container to default. + * + * - Parameter container: Container whose text color will be reset, defaults to `PDFContainer.contentLeft` + */ public func resetTextColor(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left) { objects += [(container, PDFTextColorObject(color: Color.black))] } @@ -186,8 +180,11 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Table /** - Adds a table object to the document in the defined container - */ + * Adds a table object to the document in the defined container + * + * - Parameter container: Container where the table color will be added, defaults to `PDFContainer.contentLeft` + * - Parameter color: Table to add to document + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, table: PDFTable) { objects += [(container, PDFTableObject(table: table))] } @@ -195,8 +192,11 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - List /** - Adds a list object to the document in the defined container - */ + * Adds a list object to the document in the defined container + * + * - Parameter container: Container where the text color will be set, defaults to `PDFContainer.contentLeft` + * - Parameter color: Color of the text + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, list: PDFList) { objects += [(container, PDFListObject(list: list))] } @@ -204,22 +204,23 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Layout /** - Change the indentation in a container, use the parameter `left` to define from which side. - - - parameter container: Container whose indentation should be changed, defaults to `PDFSectionColumnContainer.left` - - parameter indent: Points from the side - - parameter left: If `true` then the left side indentation is set, else the right indentation is set - */ + * Change the indentation in a container, use the parameter `left` to define from which side. + * + * - Parameters: + * - container: Container whose indentation should be changed, defaults to `PDFContainer.contentLeft` + * - indent: Points from the side + * - left: If `true` then the left side indentation is set, else the right indentation is set + */ public func set(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, indent: CGFloat, left: Bool) { objects += [(container, PDFIndentationObject(indentation: indent, left: left, insideSectionColumn: true))] } /** - Change the absolute top offset in a container - - - parameter container: Container whose current absolute offset should be changed, defaults to `PDFSectionColumnContainer.left` - - parameter offset: Points from the top - */ + * Change the absolute top offset in a container + * + * - Parameter container: Container whose current absoilute offset should be changed, defaults to `PDFContainer.contentLeft` + * - Parameter absoluteOffset: Points from the top + */ public func set(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, absoluteOffset: CGFloat) { objects += [(container, PDFOffsetObject(offset: absoluteOffset))] } @@ -227,16 +228,21 @@ public class PDFSectionColumn: PDFDocumentObject { // MARK: - Groups /** - Adds a group object to the section column in the defined container - */ + * Adds a group + * + * - Parameter container: Container where the group will be added + * - Parameter group: Instance of ``PDFGroup`` to add + */ public func add(_ container: PDFSectionColumnContainer = PDFSectionColumnContainer.left, group: PDFGroup) { - objects += [(container, PDFGroupObject(objects: group.objects, - allowsBreaks: group.allowsBreaks, - isFullPage: false, - backgroundColor: group.backgroundColor, - backgroundImage: group.backgroundImage, - backgroundShape: group.backgroundShape, - outline: group.outline, - padding: group.padding))] + objects += [(container, PDFGroupObject( + objects: group.objects, + allowsBreaks: group.allowsBreaks, + isFullPage: false, + backgroundColor: group.backgroundColor, + backgroundImage: group.backgroundImage, + backgroundShape: group.backgroundShape, + outline: group.outline, + padding: group.padding + ))] } } diff --git a/Source/API/Table Of Content/PDFTableOfContent.swift b/Source/API/Table Of Content/PDFTableOfContent.swift index 33f21721..286486bf 100644 --- a/Source/API/Table Of Content/PDFTableOfContent.swift +++ b/Source/API/Table Of Content/PDFTableOfContent.swift @@ -5,40 +5,86 @@ // Created by Philip Niedertscheider on 28.05.19. // -import Foundation +/// Internal utility type alias for weak references to document wide text styles +typealias WeakPDFTextStyleRef = WeakRef /** - Type alias for weak references to document wide text styles - */ -internal typealias WeakPDFTextStyleRef = WeakRef + Creates a table of content for the given list of render objects. -/** - TODO: Documentation - */ + The given list of `styles` are used to identify which ``PDFAttributedTextObject`` should be considered as "headers" + and therefore be in the table of contents. + + Furthermore, the index of the style in the list of `styles` is used as the nesting level. + + Looking at the following example document, there are 3 levels of headers defined: + - **Title** + - **Heading 1** + - **Heading 2** + + Any other text which is not using these styles, should be considered body content text. + + let document = PDFDocument(format: .a4) + + // Define document wide styles + let titleStyle = document.add(style: PDFTextStyle(name: "Title")) + let headingStyle1 = document.add(style: PDFTextStyle(name: "Heading 1")) + let headingStyle2 = document.add(style: PDFTextStyle(name: "Heading 2")) + + // Add a string using the title style + document.add(textObject: PDFSimpleText(text: "TPPDF", style: titleStyle)) + + // Add a table of content, the content will be calculated based on the usages of the styles + document.add(text: "Table of Contents") + document.add(tableOfContent: PDFTableOfContent(styles: [ + headingStyle1, + headingStyle2, + ], symbol: .none)) + + // Add headline with extra spacing + document.add(textObject: PDFSimpleText(text: "1. Introduction", style: headingStyle1)) + document.add(text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry.") + + document.add(textObject: PDFSimpleText(text: "2. Images", style: headingStyle1)) + document.add(text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry.") + + document.add(textObject: PDFSimpleText(text: "2.1 Special Images", style: headingStyle2)) + document.add(text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry.") + + document.add(textObject: PDFSimpleText(text: "3. Tables", style: headingStyle1)) + document.add(text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry.") + + The output of the table of contents nested lists will look like this: + + - 1. Introduction + - 2. Images + - 2.1 Special Images + - 3. Tables + + */ public class PDFTableOfContent: PDFDocumentObject { + /// List of weak references to ``PDFTextStyle`` used internally to render the Table Of Contents + var styles: [WeakPDFTextStyleRef] /** - TODO: Documentation - */ - internal var styles: [WeakPDFTextStyleRef] + Symbol used in the ``PDFList`` after converting the table of contents. - /** - TODO: Documentation + See ``PDFListItem/symbol`` for further information */ public var symbol: PDFListItemSymbol /** - TODO: Documentation + Creates a new Table Of Contents by selecting render objects matching the given `styles` + + - Parameter styles: List of ``PDFTextStyle`` to select the relevant ``PDFAttributedText`` objects in the document + - Parameter symbol: Symbol used for the resulting `PDFList` */ public init(styles: [PDFTextStyle], symbol: PDFListItemSymbol) { self.styles = styles.map(WeakPDFTextStyleRef.init(value:)) self.symbol = symbol } - /** - TODO: Documentation - */ - internal var copy: PDFTableOfContent { + /// nodoc + var copy: PDFTableOfContent { let object = PDFTableOfContent(styles: [], symbol: symbol) object.styles = Array(styles) return object diff --git a/Source/API/Table/Content/NSAttributedString+PDFTableContent.swift b/Source/API/Table/Content/NSAttributedString+PDFTableContent.swift index ac9a8c09..ad768cf0 100644 --- a/Source/API/Table/Content/NSAttributedString+PDFTableContent.swift +++ b/Source/API/Table/Content/NSAttributedString+PDFTableContent.swift @@ -7,14 +7,9 @@ import Foundation -/** - Adds functionality to convert to PDF table content - */ +/// Adds functionality to convert to PDF table content extension NSAttributedString: PDFTableContentable { - - /** - - returns: Instance of `PDFTableContent` of type attributed string, using self as content - */ + /// Instance of ``PDFTableContent`` of type attributed string, using `self` as content public var asTableContent: PDFTableContent { PDFTableContent(type: .attributedString, content: self) } diff --git a/Source/API/Table/Content/Number+PDFTableContentable.swift b/Source/API/Table/Content/Number+PDFTableContentable.swift index fd683745..58685950 100644 --- a/Source/API/Table/Content/Number+PDFTableContentable.swift +++ b/Source/API/Table/Content/Number+PDFTableContentable.swift @@ -5,22 +5,28 @@ // Created by Philip Niedertscheider on 16.05.20. // -extension Int: PDFTableContentable { +// MARK: - Int + PDFTableContentable +extension Int: PDFTableContentable { + /// Converts this ``Int`` to a ``PDFTableContent`` public var asTableContent: PDFTableContent { String(describing: self).asTableContent } } -extension Double: PDFTableContentable { +// MARK: - Double + PDFTableContentable +extension Double: PDFTableContentable { + /// Converts this ``Double`` to a ``PDFTableContent`` public var asTableContent: PDFTableContent { String(describing: self).asTableContent } } -extension Float: PDFTableContentable { +// MARK: - Float + PDFTableContentable +extension Float: PDFTableContentable { + /// Converts this ``Float`` to a ``PDFTableContent`` public var asTableContent: PDFTableContent { String(describing: self).asTableContent } diff --git a/Source/API/Table/Content/PDFTableContent+ContentType.swift b/Source/API/Table/Content/PDFTableContent+ContentType.swift index 8ae28db2..20e8b388 100644 --- a/Source/API/Table/Content/PDFTableContent+ContentType.swift +++ b/Source/API/Table/Content/PDFTableContent+ContentType.swift @@ -1,39 +1,23 @@ // -// PDFTableContent.swift +// PDFTableContent+ContentType.swift // TPPDF // // Created by Philip Niedertscheider on 13/06/2017. // -/** - TODO: Documentation - */ -extension PDFTableContent { - - /** - TODO: Documentation - */ - internal enum ContentType { - - /** - TODO: Documentation - */ +public extension PDFTableContent { + /// Internal enumeration type used to identify the type-erased ``PDFTableContent/content`` + enum ContentType { + /// Undefined content type case none - /** - TODO: Documentation - */ + /// Content is a string value case string - /** - TODO: Documentation - */ + /// Content is an attributed string case attributedString - /** - TODO: Documentation - */ + /// Content is an image case image - } } diff --git a/Source/API/Table/Content/PDFTableContent.swift b/Source/API/Table/Content/PDFTableContent.swift index f5b1bdf8..afa9e378 100644 --- a/Source/API/Table/Content/PDFTableContent.swift +++ b/Source/API/Table/Content/PDFTableContent.swift @@ -6,124 +6,117 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ +/// Structure used to manage cell content public class PDFTableContent: CustomStringConvertible, Hashable { + /// Type of the content + var type: ContentType = .none - /** - TODO: Documentation - */ - internal var type: ContentType = ContentType.none - - /** - TODO: Documentation - */ - internal var content: Any? + /// Content of a cell + var content: Any? /** - TODO: Documentation + * Creates a new table cell content wrapping the given `content + * + * - Parameter content: Content of this cell, see ``ContentType`` for list of supported types. + * + * - Throws: ``PDFError/tableContentInvalid(value:)`` if the `content` has an unsupported type */ public init(content: Any?) throws { - try self.setContent(content: content) + try setContent(content: content) } /** - TODO: Documentation + * Creates a new table cell content with a pre-defined `type` and `content`. + * + * - Parameter content: Content of this cell, see ``ContentType`` for list of supported types. + * - Note: This initializer should remain internal, so that accidentally setting the wrong `type` for a `content` can be avoided */ - internal init(type: ContentType, content: Any?) { + init(type: ContentType, content: Any?) { self.type = type self.content = content } /** - TODO: Documentation + * Sets the ``PDFTableContent/content`` and ``PDFTableContent/type`` based on the given `content`. + * + * - Parameter content: Content of this cell, see ``ContentType`` for list of supported types. + * + * - Throws: ``PDFError/tableContentInvalid(value:)`` if the `content` has an unsupported type */ - internal func setContent(content: Any?) throws { + func setContent(content: Any?) throws { if content == nil { - self.type = .none + type = .none self.content = nil } else if content is String { - self.type = .string + type = .string self.content = content } else if content is Image { - self.type = .image + type = .image self.content = content } else if content is NSAttributedString { - self.type = .attributedString + type = .attributedString self.content = content } else if content is Int || content is Double || content is Float { - self.type = .string + type = .string self.content = String(describing: content!) } else { throw PDFError.tableContentInvalid(value: content) } } - /** - TODO: Documentation - */ - internal var isString: Bool { + /// Convenience accessor for testing the ``PDFTableContent/type`` + var isString: Bool { type == .string } - /** - TODO: Documentation - */ - internal var isAttributedString: Bool { + /// Convenience accessor for testing the ``PDFTableContent/type`` + var isAttributedString: Bool { type == .attributedString } - /** - TODO: Documentation - */ - internal var isImage: Bool { + /// Convenience accessor for testing the ``PDFTableContent/type`` + var isImage: Bool { type == .image } - /** - TODO: Documentation - */ - internal var stringValue: String? { + /// Convenience accessor for casting the ``PDFTableContent/content`` based on the ``PDFTableContent/type`` + var stringValue: String? { type == .string ? content as? String : nil } - /** - TODO: Documentation - */ - internal var attributedStringValue: NSAttributedString? { + /// Convenience accessor for casting the ``PDFTableContent/content`` based on the ``PDFTableContent/type`` + var attributedStringValue: NSAttributedString? { type == .attributedString ? content as? NSAttributedString : nil } - /** - TODO: Documentation - */ - internal var imageValue: Image? { + /// Convenience accessor for casting the ``PDFTableContent/content`` based on the ``PDFTableContent/type`` + var imageValue: Image? { type == .image ? content as? Image : nil } // MARK: - Equatable + /// nodoc public static func == (lhs: PDFTableContent, rhs: PDFTableContent) -> Bool { guard lhs.type == rhs.type else { return false } if let lhsString = lhs.content as? String, - let rhsString = rhs.content as? String, - lhsString != rhsString { + let rhsString = rhs.content as? String, + lhsString != rhsString { return false } else if let lhsString = lhs.content as? NSAttributedString, - let rhsString = rhs.content as? NSAttributedString, - lhsString != rhsString { + let rhsString = rhs.content as? NSAttributedString, + lhsString != rhsString { return false } else if let lhsImage = lhs.content as? Image, - let rhsImage = rhs.content as? Image, - lhsImage != rhsImage { + let rhsImage = rhs.content as? Image, + lhsImage != rhsImage { return false } else if (lhs.content == nil && rhs.content != nil) || (lhs.content != nil && rhs.content == nil) { return false @@ -133,6 +126,7 @@ public class PDFTableContent: CustomStringConvertible, Hashable { // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(type) switch type { @@ -148,8 +142,10 @@ public class PDFTableContent: CustomStringConvertible, Hashable { } } -extension PDFTableContent: PDFTableContentable { +// MARK: PDFTableContentable +extension PDFTableContent: PDFTableContentable { + /// Casts this instance to a ``PDFTableContent`` public var asTableContent: PDFTableContent { self } diff --git a/Source/API/Table/Content/PDFTableContentable.swift b/Source/API/Table/Content/PDFTableContentable.swift index ec6bed6c..253ded8c 100644 --- a/Source/API/Table/Content/PDFTableContentable.swift +++ b/Source/API/Table/Content/PDFTableContentable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 16.05.20. // -/** - Adds functionality to convert to a PDF table content - */ +/// Protocol to extend a type with a converter to ``PDFTableContent`` public protocol PDFTableContentable { - - /** - - returns: `PDFTableContent` with correct type and holding data - */ + /// Instance of ``PDFTableContent`` holding `self` as the content value var asTableContent: PDFTableContent { get } - } diff --git a/Source/API/Table/Content/String+PDFTableContent.swift b/Source/API/Table/Content/String+PDFTableContent.swift index 133a27d2..a7273f7b 100644 --- a/Source/API/Table/Content/String+PDFTableContent.swift +++ b/Source/API/Table/Content/String+PDFTableContent.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 20.12.19. // -/** - Adds functionality to convert to PDF table content - */ extension String: PDFTableContentable { - - /** - - returns: Instance of `PDFTableContent` of type string, using self as content - */ + /// Instance of ``PDFTableContent`` holding `self` as the content value public var asTableContent: PDFTableContent { PDFTableContent(type: .string, content: self) } diff --git a/Source/API/Table/Content/UIImage+PDFTableContent.swift b/Source/API/Table/Content/UIImage+PDFTableContent.swift index d0347886..358d0d06 100644 --- a/Source/API/Table/Content/UIImage+PDFTableContent.swift +++ b/Source/API/Table/Content/UIImage+PDFTableContent.swift @@ -1,24 +1,20 @@ // -// Image+PDFTableContent.swift +// UIImage+PDFTableContent.swift // TPPDF // // Created by Philip Niedertscheider on 20.12.19. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - Adds functionality to convert to PDF table content - */ -extension Image: PDFTableContentable { +// MARK: - Image + PDFTableContentable - /** - - returns: Instance of `PDFTableContent` of type image, using self as content - */ +extension Image: PDFTableContentable { + /// Instance of ``PDFTableContent`` holding `self` as the content value public var asTableContent: PDFTableContent { PDFTableContent(type: .image, content: self) } diff --git a/Source/API/Table/PDFTable.swift b/Source/API/Table/PDFTable.swift index c6cfd9ea..56a19d67 100644 --- a/Source/API/Table/PDFTable.swift +++ b/Source/API/Table/PDFTable.swift @@ -6,150 +6,142 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - A table is a two dimensional list. - It can be styled and can contain different data. + * A table is a two dimensional list. + * + * It can be styled and can contain different data. */ public class PDFTable: PDFDocumentObject { - - /** - Styling used for drawing - */ + /// Styling used for drawing public var style: PDFTableStyle = PDFTableStyleDefaults.simple - /** - All cell data - */ + /// Two-dimensional array of cells public var cells: [[PDFTableCell]] = [] /** - List of relative widths. Values are between 0.0 and 1.0 and should sum up to 1.0 + * List of relative horizontal column widths. + * + * Values are between `0.0` and `1.0` and should sum up to `1.0` (100%) */ public var widths: [CGFloat] = [] - /** - Padding is the distance between the cell content and its borders. - */ + /// Padding is the distance between the cell content and its borders. public var padding: CGFloat = 0 - /** - Margin is the distance between the cell borders and other cells - */ + /// Margin is the distance between the cell borders and other cells public var margin: CGFloat = 0 - /** - Header rows will be drawn on every page - */ + /// Header rows will be drawn on every page public var showHeadersOnEveryPage: Bool = false - /** - Cells should split when overlapping page - */ + //// Cells should split when overlapping page public var shouldSplitCellsOnPageBreak = false /** - Count of rows and columns in this table + * Count of rows and columns in this table + * + * The size of the table needs to be defined beforehand, so that cells can be accessed using subscript accessors */ public private(set) var size: (rows: Int, columns: Int) - /// Creates a new table with the given size and populates it with empty cells - /// - /// - Parameter size: Row and column count of table + /** + * Creates a new table with the given size and populates it with empty cells + * + * - Parameter size: Row and column count of table + */ public convenience init(size: (rows: Int, columns: Int)) { self.init(rows: size.rows, columns: size.columns) } - /// Creates a new table with the given size and populates it with empty cells. - /// - Parameters: - /// - rows: Rows of table, must be greater than 0 - /// - columns: Columns of table, must be greater than 0 + /** + * Creates a new table with the given size and populates it with empty cells. + * - Parameters: + * - rows: Rows of table, must be greater than 0 + * - columns: Columns of table, must be greater than 0 + */ public init(rows: Int, columns: Int) { assert(rows >= 0, "Can't create a table with negative row count") assert(columns >= 0, "Can't create a table with negative column count") self.size = (rows: rows, columns: columns) - self.cells = (0.. Bool { guard super.isEqual(to: other) else { return false } guard let otherTable = other as? PDFTable else { return false } - guard self.style == otherTable.style else { + guard style == otherTable.style else { return false } - guard self.cells.count == otherTable.cells.count else { + guard cells.count == otherTable.cells.count else { return false } - for i in 0.. Bool { guard super.isEqual(to: other) else { return false @@ -56,13 +45,13 @@ public class PDFTableCell: PDFDocumentObject { guard let otherCell = other as? PDFTableCell else { return false } - guard self.content == otherCell.content else { + guard content == otherCell.content else { return false } - guard self.style == otherCell.style else { + guard style == otherCell.style else { return false } - guard self.alignment == otherCell.alignment else { + guard alignment == otherCell.alignment else { return false } return true @@ -70,6 +59,7 @@ public class PDFTableCell: PDFDocumentObject { // MARK: - Equatable + /// nodoc override public func hash(into hasher: inout Hasher) { super.hash(into: &hasher) hasher.combine(content) diff --git a/Source/API/Table/PDFTableCellAlignment.swift b/Source/API/Table/PDFTableCellAlignment.swift index 05579fe0..e6b5be2c 100644 --- a/Source/API/Table/PDFTableCellAlignment.swift +++ b/Source/API/Table/PDFTableCellAlignment.swift @@ -5,60 +5,37 @@ // Created by Philip Niedertscheider on 11/08/2017. // -/** - Options for aligning content inside a table cell - */ +/// Options for aligning content inside a table cell public enum PDFTableCellAlignment: String { - - /** - Content will be aligned in the top left corner - */ + /// Content will be aligned in the top left corner case topLeft = "top-left" - /** - Content will be aligned with the top edge, centered horizontally - */ - case top = "top" + /// Content will be aligned with the top edge, centered horizontally + case top - /** - Content will be aligned in the top right corner - */ + /// Content will be aligned in the top right corner case topRight = "top-right" - /** - Content will be aligned with the left edge, centered vertically - */ - case left = "left" + /// Content will be aligned with the left edge, centered vertically + case left - /** - Content will be centered horizontally & vertically - */ - case center = "center" + /// Content will be centered horizontally & vertically + case center - /** - Content will be aligned with the right edge, centered horizontally - */ - case right = "right" + /// Content will be aligned with the right edge, centered horizontally + case right - /** - Content will be aligned in the bottom left corner - */ + /// Content will be aligned in the bottom left corner case bottomLeft = "bottom-left" - /** - Content will be aligned with the bottom edge, centered horizontally - */ - case bottom = "bottom" + /// Content will be aligned with the bottom edge, centered horizontally + case bottom - /** - Content will be aligned in the top right corner - */ + /// Content will be aligned in the top right corner case bottomRight = "bottom-right" - /** - Alignment is at the top edge - */ - internal var isTop: Bool { + /// Alignment is at the top edge + var isTop: Bool { switch self { case .topLeft, .top, .topRight: return true @@ -67,10 +44,8 @@ public enum PDFTableCellAlignment: String { } } - /** - Alignment is at the bottom side - */ - internal var isBottom: Bool { + /// Alignment is at the bottom side + var isBottom: Bool { switch self { case .bottomLeft, .bottom, .bottomRight: return true @@ -79,10 +54,8 @@ public enum PDFTableCellAlignment: String { } } - /** - Alignment is on the left side - */ - internal var isLeft: Bool { + /// Alignment is on the left side + var isLeft: Bool { switch self { case .topLeft, .left, .bottomLeft: return true @@ -91,10 +64,8 @@ public enum PDFTableCellAlignment: String { } } - /** - Alignment is on the right side - */ - internal var isRight: Bool { + /// Alignment is on the right side + var isRight: Bool { switch self { case .topRight, .right, .bottomRight: return true diff --git a/Source/API/Table/PDFTableCellPosition.swift b/Source/API/Table/PDFTableCellPosition.swift index d0f9b0b7..58a1c2b9 100644 --- a/Source/API/Table/PDFTableCellPosition.swift +++ b/Source/API/Table/PDFTableCellPosition.swift @@ -5,24 +5,15 @@ // Created by Philip Niedertscheider on 11/08/2017. // -/** - A cell position represent the coordinate of a cell in a given table - */ +/// A cell position represent the coordinate of a cell in a given table public struct PDFTableCellPosition { - - /** - Vertical row index, starting at zero - */ + /// Vertical row index, starting at zero public var row: Int - /** - Horizontal column index, starting at zero - */ + /// Horizontal column index, starting at zero public var column: Int - /** - Creates a new position with the given row and column - */ + /// Creates a new position with the given row and column public init(row: Int, column: Int) { self.row = row self.column = column diff --git a/Source/API/Table/Sections/PDFTable+CellSubscripts.swift b/Source/API/Table/Sections/PDFTable+CellSubscripts.swift index c71d3b05..32237039 100644 --- a/Source/API/Table/Sections/PDFTable+CellSubscripts.swift +++ b/Source/API/Table/Sections/PDFTable+CellSubscripts.swift @@ -1,5 +1,5 @@ // -// PDFTable+SingleCellSubscripts.swift +// PDFTable+CellSubscripts.swift // TPPDF // // Created by Philip Niedertscheider on 22.12.19. @@ -7,17 +7,15 @@ import Foundation -extension PDFTable { - +public extension PDFTable { /** - Accessor for a specific cell at the given position - - - parameter row: Index of row - - parameter column: Index of column - - - returns: cell at given indicies + * Accessor for a specific ``PDFTableCell`` at the given position + * + * - Parameter position: ``PDFTableCellPosition`` with row and column index + * + * - Returns: ``PDFTableCell`` at the given position */ - public subscript(position position: PDFTableCellPosition) -> PDFTableCell { + subscript(position position: PDFTableCellPosition) -> PDFTableCell { get { self[position.row, position.column] } @@ -27,19 +25,19 @@ extension PDFTable { } /** - Accessor for a specific cell at the given position - - - parameter row: Index of row - - parameter column: Index of column - - - returns: cell at given indicies + * Accessor for a specific cell at the given position + * + * - Parameter row: Index of row + * - Parameter column: Index of column + * + * - Returns: ``PDFTableCell``at the given position */ - public subscript(row: Int, column: Int) -> PDFTableCell { + subscript(row: Int, column: Int) -> PDFTableCell { get { - self.cells[row][column] + cells[row][column] } set { - self.cells[row][column] = newValue + cells[row][column] = newValue } } } diff --git a/Source/API/Table/Sections/PDFTable+ColumnSubscripts.swift b/Source/API/Table/Sections/PDFTable+ColumnSubscripts.swift index e61b57dd..6b6e5ad1 100644 --- a/Source/API/Table/Sections/PDFTable+ColumnSubscripts.swift +++ b/Source/API/Table/Sections/PDFTable+ColumnSubscripts.swift @@ -1,5 +1,5 @@ // -// PDFTable+Subscripts.swift +// PDFTable+ColumnSubscripts.swift // TPPDF // // Created by Philip Niedertscheider on 20.12.19. @@ -7,34 +7,33 @@ import Foundation -extension PDFTable { - +public extension PDFTable { /** - Accessor for a specific column - - - parameter column: Index of column - - - returns: `PDFTableColumn` with references to cells of this table + * Accessor for a specific column + * + * - Parameter column: Index of column + * + * - Returns: ``PDFTableColumn`` with references to cells of this table */ - public subscript(column index: Int) -> PDFTableColumn { + subscript(column index: Int) -> PDFTableColumn { get { - PDFTableColumn(cells: self.cells.map({ row in row[index] }), of: self, at: index) + PDFTableColumn(cells: cells.map { row in row[index] }, of: self, at: index) } set { - for idx in self.cells.indices { - self.cells[idx][index] = newValue.cells[idx] + for idx in cells.indices { + cells[idx][index] = newValue.cells[idx] } } } /** - Accessors of columns in the given range. - - - parameter columns: Range of indicies - - - returns: `PDFTableColumns` with references to columns + * Accessors of columns in the given range. + * + * - Parameter columns: Range of indicies + * + * - Returns: `PDFTableColumns` with references to columns */ - public subscript(columns range: ClosedRange) -> PDFTableColumns { + subscript(columns range: ClosedRange) -> PDFTableColumns { get { self[columns: range.relative(to: cells[0])] } @@ -44,13 +43,13 @@ extension PDFTable { } /** - Accessors of columns in the given range. - - - parameter columns: Range of indicies - - - returns: `PDFTableColumns` with references to columns + * Accessors of columns in the given range. + * + * - Parameter columns: Range of indicies + * + * - Returns: `PDFTableColumns` with references to columns */ - public subscript(columns range: PartialRangeFrom) -> PDFTableColumns { + subscript(columns range: PartialRangeFrom) -> PDFTableColumns { get { self[columns: range.relative(to: cells[0])] } @@ -60,13 +59,13 @@ extension PDFTable { } /** - Accessors of columns in the given range. - - - parameter columns: Range of indicies - - - returns: `PDFTableColumns` with references to columns + * Accessors of columns in the given range. + * + * - Parameter columns: Range of indicies + * + * - Returns: `PDFTableColumns` with references to columns */ - public subscript(columns range: PartialRangeThrough) -> PDFTableColumns { + subscript(columns range: PartialRangeThrough) -> PDFTableColumns { get { self[columns: range.relative(to: cells[0])] } @@ -76,13 +75,13 @@ extension PDFTable { } /** - Accessors of columns in the given range. - - - parameter columns: Range of indicies - - - returns: `PDFTableColumns` with references to columns + * Accessors of columns in the given range. + * + * - Parameter columns: Range of indicies + * + * - Returns: `PDFTableColumns` with references to columns */ - public subscript(columns range: PartialRangeUpTo) -> PDFTableColumns { + subscript(columns range: PartialRangeUpTo) -> PDFTableColumns { get { self[columns: range.relative(to: cells[0])] } @@ -92,22 +91,23 @@ extension PDFTable { } /** - Accessors of columns in the given range. - - - parameter columns: Range of indicies - - - returns: `PDFTableColumns` with references to columns + * Accessors of columns in the given range. + * + * - Parameter columns: Range of indicies + * + * - Returns: `PDFTableColumns` with references to columns */ - public subscript(columns range: Range) -> PDFTableColumns { + subscript(columns range: Range) -> PDFTableColumns { get { PDFTableColumns( columns: range - .map({ column in - (position: column, cells: self.cells.map({ $0[column] })) - }) - .map({ PDFTableColumn.init(cells: $0.cells, of: self, at: $0.position) }), + .map { column in + (position: column, cells: self.cells.map { $0[column] }) + } + .map { PDFTableColumn(cells: $0.cells, of: self, at: $0.position) }, of: self, - in: range) + in: range + ) } set { for (colIdx, column) in range.enumerated() { diff --git a/Source/API/Table/Sections/PDFTable+RowSubscripts.swift b/Source/API/Table/Sections/PDFTable+RowSubscripts.swift index 66c8e24e..e7598e2e 100644 --- a/Source/API/Table/Sections/PDFTable+RowSubscripts.swift +++ b/Source/API/Table/Sections/PDFTable+RowSubscripts.swift @@ -1,5 +1,5 @@ // -// PDFTable+SingleCellSubscripts.swift +// PDFTable+RowSubscripts.swift // TPPDF // // Created by Philip Niedertscheider on 22.12.19. @@ -7,32 +7,31 @@ import Foundation -extension PDFTable { - +public extension PDFTable { /** - Accessor for a specific row - - - parameter row: Index of row - - - returns: `PDFTableRow` with references to cells of this table + * Accessor for a specific row + * + * - Parameter row: Index of row + * + * - Returns: ``PDFTableRow`` with references to cells of this table */ - public subscript(row index: Int) -> PDFTableRow { + subscript(row index: Int) -> PDFTableRow { get { - PDFTableRow(cells: self.cells[index], of: self, at: index) + PDFTableRow(cells: cells[index], of: self, at: index) } set { - self.cells[index] = newValue.cells + cells[index] = newValue.cells } } /** - Accessors of rows in the given range. - - - parameter rows: Range of indicies - - - returns: `PDFTableRows` with references to rows + * Accessor for multiple rows in the given range `rows` + * + * - Parameter rows: Range of indicies + * + * - Returns: ``PDFTableRows`` with references to rows */ - public subscript(rows range: ClosedRange) -> PDFTableRows { + subscript(rows range: ClosedRange) -> PDFTableRows { get { self[rows: range.relative(to: cells)] } @@ -42,13 +41,13 @@ extension PDFTable { } /** - Accessors of rows in the given range. - - - parameter rows: Range of indicies - - - returns: `PDFTableRows` with references to rows + * Accessor for multiple rows in the given range `rows` + * + * - Parameter rows: Range of indicies + * + * - Returns: ``PDFTableRows`` with references to rows */ - public subscript(rows range: PartialRangeFrom) -> PDFTableRows { + subscript(rows range: PartialRangeFrom) -> PDFTableRows { get { self[rows: range.relative(to: cells)] } @@ -58,13 +57,13 @@ extension PDFTable { } /** - Accessors of rows in the given range. - - - parameter rows: Range of indicies - - - returns: `PDFTableRows` with references to rows + * Accessor for multiple rows in the given range `rows` + * + * - Parameter rows: Range of indicies + * + * - Returns: ``PDFTableRows`` with references to rows */ - public subscript(rows range: PartialRangeThrough) -> PDFTableRows { + subscript(rows range: PartialRangeThrough) -> PDFTableRows { get { self[rows: range.relative(to: cells)] } @@ -74,13 +73,13 @@ extension PDFTable { } /** - Accessors of rows in the given range. - - - parameter rows: Range of indicies - - - returns: `PDFTableRows` with references to rows + * Accessor for multiple rows in the given range `rows` + * + * - Parameter rows: Range of indicies + * + * - Returns: ``PDFTableRows`` with references to rows */ - public subscript(rows range: PartialRangeUpTo) -> PDFTableRows { + subscript(rows range: PartialRangeUpTo) -> PDFTableRows { get { self[rows: range.relative(to: cells)] } @@ -90,20 +89,21 @@ extension PDFTable { } /** - Accessors of rows in the given range. - - - parameter rows: Range of indicies - - - returns: `PDFTableRows` with references to rows + * Accessor for multiple rows in the given range `rows` + * + * - Parameter rows: Range of indicies + * + * - Returns: ``PDFTableRows`` with references to rows */ - public subscript(rows range: Range) -> PDFTableRows { + subscript(rows range: Range) -> PDFTableRows { get { PDFTableRows( rows: range - .map({ (position: $0, cells: self.cells[$0]) }) - .map({ PDFTableRow.init(cells: $0.cells, of: self, at: $0.position) }), + .map { (position: $0, cells: self.cells[$0]) } + .map { PDFTableRow(cells: $0.cells, of: self, at: $0.position) }, of: self, - in: range) + in: range + ) } set { for (rowIdx, row) in range.enumerated() { diff --git a/Source/API/Table/Sections/PDFTable+SectionSubscripts.swift b/Source/API/Table/Sections/PDFTable+SectionSubscripts.swift index 58913f47..fd26e20d 100644 --- a/Source/API/Table/Sections/PDFTable+SectionSubscripts.swift +++ b/Source/API/Table/Sections/PDFTable+SectionSubscripts.swift @@ -1,5 +1,5 @@ // -// PDFTable+Subscripts.swift +// PDFTable+SectionSubscripts.swift // TPPDF // // Created by Philip Niedertscheider on 20.12.19. @@ -9,19 +9,18 @@ import Foundation -extension PDFTable { - +public extension PDFTable { // MARK: - Single Row /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows row: Int, columns columns: Range) -> PDFTableSection { + subscript(rows row: Int, columns columns: Range) -> PDFTableSection { get { self[rows: row...row, columns: columns.relative(to: cells[0])] } @@ -31,14 +30,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows row: Int, columns columns: ClosedRange) -> PDFTableSection { + subscript(rows row: Int, columns columns: ClosedRange) -> PDFTableSection { get { self[rows: row...row, columns: columns.relative(to: cells[0])] } @@ -48,14 +47,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows row: Int, columns columns: PartialRangeFrom) -> PDFTableSection { + subscript(rows row: Int, columns columns: PartialRangeFrom) -> PDFTableSection { get { self[rows: row...row, columns: columns.relative(to: cells[0])] } @@ -65,14 +64,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows row: Int, columns columns: PartialRangeThrough) -> PDFTableSection { + subscript(rows row: Int, columns columns: PartialRangeThrough) -> PDFTableSection { get { self[rows: row...row, columns: columns.relative(to: cells[0])] } @@ -82,14 +81,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows row: Int, columns columns: PartialRangeUpTo) -> PDFTableSection { + subscript(rows row: Int, columns columns: PartialRangeUpTo) -> PDFTableSection { get { self[rows: row...row, columns: columns.relative(to: cells[0])] } @@ -101,14 +100,14 @@ extension PDFTable { // MARK: - Range /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, columns columns: ClosedRange) -> PDFTableSection { + subscript(rows rows: Range, columns columns: ClosedRange) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -118,14 +117,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, columns columns: PartialRangeFrom) -> PDFTableSection { + subscript(rows rows: Range, columns columns: PartialRangeFrom) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -135,14 +134,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, columns columns: PartialRangeThrough) -> PDFTableSection { + subscript(rows rows: Range, columns columns: PartialRangeThrough) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -152,14 +151,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, columns columns: PartialRangeUpTo) -> PDFTableSection { + subscript(rows rows: Range, columns columns: PartialRangeUpTo) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -169,14 +168,14 @@ extension PDFTable { } /** - Accessors of column in the given rows - - - parameter rows: Range of indicies - - parameter column: Single row index - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, column column: Int) -> PDFTableSection { + subscript(rows rows: Range, column column: Int) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: column...column] } @@ -188,14 +187,14 @@ extension PDFTable { // MARK: - Closed Range /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, columns columns: Range) -> PDFTableSection { + subscript(rows rows: ClosedRange, columns columns: Range) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -205,14 +204,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, columns columns: ClosedRange) -> PDFTableSection { + subscript(rows rows: ClosedRange, columns columns: ClosedRange) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -222,14 +221,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, columns columns: PartialRangeFrom) -> PDFTableSection { + subscript(rows rows: ClosedRange, columns columns: PartialRangeFrom) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -239,14 +238,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, columns columns: PartialRangeThrough) -> PDFTableSection { + subscript(rows rows: ClosedRange, columns columns: PartialRangeThrough) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -256,14 +255,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, columns columns: PartialRangeUpTo) -> PDFTableSection { + subscript(rows rows: ClosedRange, columns columns: PartialRangeUpTo) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -273,14 +272,14 @@ extension PDFTable { } /** - Accessors of column in the given rows - - - parameter rows: Range of indicies - - parameter column: Single row index - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: ClosedRange, column column: Int) -> PDFTableSection { + subscript(rows rows: ClosedRange, column column: Int) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: column...column] } @@ -292,14 +291,14 @@ extension PDFTable { // MARK: - Partial Range From /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, columns columns: Range) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, columns columns: Range) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -309,14 +308,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, columns columns: ClosedRange) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, columns columns: ClosedRange) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -326,14 +325,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeFrom) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeFrom) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -343,14 +342,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeThrough) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeThrough) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -360,14 +359,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeUpTo) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, columns columns: PartialRangeUpTo) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -377,14 +376,14 @@ extension PDFTable { } /** - Accessors of column in the given rows - - - parameter rows: Range of indicies - - parameter column: Single row index - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeFrom, column column: Int) -> PDFTableSection { + subscript(rows rows: PartialRangeFrom, column column: Int) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: column...column] } @@ -396,14 +395,14 @@ extension PDFTable { // MARK: - Partial Range Up To /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, columns columns: Range) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, columns columns: Range) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -413,14 +412,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, columns columns: ClosedRange) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, columns columns: ClosedRange) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -430,14 +429,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeFrom) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeFrom) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -447,14 +446,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeThrough) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeThrough) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -464,14 +463,14 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeUpTo) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, columns columns: PartialRangeUpTo) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: columns.relative(to: cells[0])] } @@ -481,14 +480,14 @@ extension PDFTable { } /** - Accessors of column in the given rows - - - parameter rows: Range of indicies - - parameter column: Single row index - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: PartialRangeUpTo, column column: Int) -> PDFTableSection { + subscript(rows rows: PartialRangeUpTo, column column: Int) -> PDFTableSection { get { self[rows: rows.relative(to: cells), columns: column...column] } @@ -498,21 +497,21 @@ extension PDFTable { } /** - Accessors of cells in the given rows and columns range. - - - parameter rows: Range of indicies - - parameter columns: Range of indicies - - - returns: `PDFTableSection` with references to cells + * Accessors to the cells in the section defined by given ranges `rows` and `columns` + * + * - Parameter rows: Range of indicies + * - Parameter columns: Range of indicies + * + * - Returns: ``PDFTableSection`` with references to cells */ - public subscript(rows rows: Range, columns columns: Range) -> PDFTableSection { + subscript(rows rows: Range, columns columns: Range) -> PDFTableSection { get { - PDFTableSection(cells: self.cells[rows].map({ Array($0[columns]) }), of: self, in: rows, and: columns) + PDFTableSection(cells: cells[rows].map { Array($0[columns]) }, of: self, in: rows, and: columns) } set { for (rowIdx, row) in rows.enumerated() { for (colIdx, column) in columns.enumerated() { - self.cells[row][column] = newValue.cells[rowIdx][colIdx] + cells[row][column] = newValue.cells[rowIdx][colIdx] } } } diff --git a/Source/API/Table/Sections/PDFTableColumn.swift b/Source/API/Table/Sections/PDFTableColumn.swift index 3e1ea81a..24a23e54 100644 --- a/Source/API/Table/Sections/PDFTableColumn.swift +++ b/Source/API/Table/Sections/PDFTableColumn.swift @@ -7,28 +7,32 @@ import Foundation -/** - Reference to a single column of cells in a `PDFTable` - */ +/// Reference to a single column of cells in a ``PDFTable`` public class PDFTableColumn { - - /** - References to the cells in the column - */ + /// References to the cells in the column public private(set) var cells: [PDFTableCell] + /// Reference to the ``PDFTable`` private let table: PDFTable + + /// Range of rows in the ``PDFTableColumn/table`` private let position: Int - internal init(cells: [PDFTableCell], of table: PDFTable, at position: Int) { + /** + * Creates a new reference to a row of cells in a table. + * + * - Parameters: + * - cells: See ``PDFTableRows/cells`` for details + * - table: See ``PDFTableRows/table`` for details + * - position: See ``PDFTableRows/position`` for details + */ + init(cells: [PDFTableCell], of table: PDFTable, at position: Int) { self.cells = cells self.table = table self.position = position } - /** - Access and modifier for a specific cell in a given row - */ + /// Access and modifier for a specific cell in a given row public subscript(row: Int) -> PDFTableCell { get { cells[row] @@ -40,9 +44,9 @@ public class PDFTableColumn { } /** - Access content of all cells in column or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in column or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var content: [PDFTableContentable?] { get { @@ -57,7 +61,9 @@ public class PDFTableColumn { } /** - Setter method to change the content of all cells in the column + * Setter method to change the content of all cells in the column + * + * - Note: This method can not be used to get contents, because the type can only be a single value. */ public var allCellsContent: PDFTableContent? { @available(*, unavailable) @@ -65,14 +71,14 @@ public class PDFTableColumn { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.content = newValue }) + cells.forEach { $0.content = newValue } } } /** - Access content of all cells in column or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in column or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var style: [PDFTableCellStyle?] { get { @@ -87,7 +93,9 @@ public class PDFTableColumn { } /** - Setter method to change the style of all cells in the column + * Setter method to change the style of all cells in the column + * + * - Note: This method can not be used to get styles, because the type can only be a single value. */ public var allCellsStyle: PDFTableCellStyle? { @available(*, unavailable) @@ -95,14 +103,14 @@ public class PDFTableColumn { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.style = newValue }) + cells.forEach { $0.style = newValue } } } /** - Access content of all cells in column or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in column or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var alignment: [PDFTableCellAlignment] { get { @@ -117,7 +125,9 @@ public class PDFTableColumn { } /** - Setter method to change the content of all cells in the column + * Setter method to change the content of all cells in the column + * + * - Note: This method can not be used to get values, because the type can only be a single value. */ public var allCellsAlignment: PDFTableCellAlignment { @available(*, unavailable) @@ -125,24 +135,25 @@ public class PDFTableColumn { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.alignment = newValue }) + cells.forEach { $0.alignment = newValue } } } } -extension PDFTableColumn: PDFTableMergable { +// MARK: PDFTableMergable +extension PDFTableColumn: PDFTableMergable { /// nodoc public func merge() { - self.merge(with: nil) + merge(with: nil) } /** - Merges all cells by replacing them with the same reference. - - If no parameter `cell` is given, the first cell in the column will be used. - - - parameter cell: Cell to use after merge, may be nil + * Merges all cells by replacing them with the same reference. + * + * If no parameter `cell` is given, the first cell in the column will be used. + * + * - Parameter cell: Cell to use after merge, may be nil */ public func merge(with cell: PDFTableCell? = nil) { for row in 0.. - internal init(columns: [PDFTableColumn], of table: PDFTable, in range: Range) { + /// Creates a new + init(columns: [PDFTableColumn], of table: PDFTable, in range: Range) { self.columns = columns self.table = table self.range = range } /** - Access content of all cells in all columns or sets the content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in all columns or sets the content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var content: [[PDFTableContentable?]] { get { @@ -37,14 +36,16 @@ public class PDFTableColumns { } set { assert(newValue.count <= columns.count, "Can not access more rows than available") - columns.enumerated().forEach { (columnIdx, column) in + for (columnIdx, column) in columns.enumerated() { column.content = newValue[columnIdx] } } } /** - Setter method to change the content of all cells in the column + * Setter method to change the content of all cells in the column + * + * - Note: This method can not be used to get contents, because the type can only be a single value per column. */ public var allColumnsContent: [PDFTableContent?] { @available(*, unavailable) @@ -57,7 +58,9 @@ public class PDFTableColumns { } /** - Setter method to change the content of all cells in the column + * Setter method to change the content of all cells in the column + * + * - Note: This method can not be used to get contents, because the type can only be a single value. */ public var allCellsContent: PDFTableContent? { @available(*, unavailable) @@ -70,9 +73,9 @@ public class PDFTableColumns { } /** - Access style of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access style of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var style: [[PDFTableCellStyle?]] { get { @@ -80,14 +83,16 @@ public class PDFTableColumns { } set { assert(newValue.count <= columns.count, "Can not access more rows than available") - columns.enumerated().forEach { (columnIdx, column) in + for (columnIdx, column) in columns.enumerated() { column.style = newValue[columnIdx] } } } /** - Setter method to change the style of all cells in the column + * Setter method to change the style of all cells in the column + * + * - Note: This method can not be used to get styles, because the type can only be a single value per column */ public var allColumnsStyle: [PDFTableCellStyle?] { @available(*, unavailable) @@ -100,7 +105,9 @@ public class PDFTableColumns { } /** - Setter method to change the style of all cells in the column + * Setter method to change the style of all cells in the column + * + * - Note: This method can not be used to get styles, because the type can only be a single value. */ public var allCellsStyle: PDFTableCellStyle? { @available(*, unavailable) @@ -113,9 +120,9 @@ public class PDFTableColumns { } /** - Access alignment of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting values, an assertion error will be thrown. + * Access alignment of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting values, an assertion error will be thrown. */ public var alignment: [[PDFTableCellAlignment]] { get { @@ -123,14 +130,16 @@ public class PDFTableColumns { } set { assert(newValue.count <= columns.count, "Can not access more rows than available") - columns.enumerated().forEach { (columnIdx, column) in + for (columnIdx, column) in columns.enumerated() { column.alignment = newValue[columnIdx] } } } /** - Setter method to change the style of all cells in the columns + * Setter method to change the style of all cells in the columns + * + * - Note: This method can not be used to get alignment, because the type can only be a single value per column */ public var allColumnsAlignment: [PDFTableCellAlignment] { @available(*, unavailable) @@ -144,7 +153,9 @@ public class PDFTableColumns { } /** - Setter method to change the style of all cells in the columns + * Setter method to change the style of all cells in the columns + * + * - Note: This method can not be used to get alignments, because the type can only be a single value. */ public var allCellsAlignment: PDFTableCellAlignment { @available(*, unavailable) @@ -157,19 +168,20 @@ public class PDFTableColumns { } } -extension PDFTableColumns: PDFTableMergable { +// MARK: PDFTableMergable +extension PDFTableColumns: PDFTableMergable { /// nodoc public func merge() { - self.merge(with: nil) + merge(with: nil) } /** - Merges all cells by replacing them with the same reference. - - If no parameter `cell` is given, the first cell in the first column will be used. - - - parameter cell: Cell to use after merge, may be nil + * Merges all cells by replacing them with the same reference. + * + * If no parameter `cell` is given, the first cell in the first column will be used. + * + * - Parameter cell: Cell to use after merge, may be nil */ public func merge(with cell: PDFTableCell? = nil) { for column in columns { diff --git a/Source/API/Table/Sections/PDFTableMergeable.swift b/Source/API/Table/Sections/PDFTableMergeable.swift index 05d8389f..9684ad5a 100644 --- a/Source/API/Table/Sections/PDFTableMergeable.swift +++ b/Source/API/Table/Sections/PDFTableMergeable.swift @@ -6,23 +6,23 @@ // /** - Object implementing this protocol should offer the functionality to merge itself into a single value + * Object implementing this protocol should offer the functionality to merge itself into a single value */ public protocol PDFTableMergable { - /** - Merges all cells by replacing them with the same reference. - See `merge(with cell:)` for more. + * Merges all cells by replacing them with the same reference. + * + * See `merge(with cell:)` for more. */ func merge() /** - Merges all cells by replacing them with the same reference. - - If parameter `cell` is given, it will be the value after the merge. - Otherwise the implementation behaviour is unknown. - - - parameter cell: Cell to use after merge, may be nil + * Merges all cells by replacing them with the same reference. + * + * If parameter `cell` is given, it will be the value after the merge. + * Otherwise the implementation behaviour is unknown. + * + * - Parameter cell: Cell to use after merge, may be nil */ func merge(with cell: PDFTableCell?) } diff --git a/Source/API/Table/Sections/PDFTableRow.swift b/Source/API/Table/Sections/PDFTableRow.swift index 0f7e67da..82d80699 100644 --- a/Source/API/Table/Sections/PDFTableRow.swift +++ b/Source/API/Table/Sections/PDFTableRow.swift @@ -7,29 +7,46 @@ import Foundation -/** - Reference to a single row of cells in a `PDFTable` - */ +/// Reference to a single row of cells in a ``PDFTable`` public class PDFTableRow { + /// Array of references to ``PDFTableCell`` in this row + public private(set) var cells: [PDFTableCell] - /** - References to the cells in the row - */ - public let cells: [PDFTableCell] - + /// Reference to the ``PDFTable`` private let table: PDFTable + + /// Range of rows in the ``PDFTableRows/table`` private let position: Int - internal init(cells: [PDFTableCell], of table: PDFTable, at position: Int) { + /** + * Creates a new reference to a row of cells in a table. + * + * - Parameters: + * - cells: See ``PDFTableRows/cells`` for details + * - table: See ``PDFTableRows/table`` for details + * - position: See ``PDFTableRows/position`` for details + */ + init(cells: [PDFTableCell], of table: PDFTable, at position: Int) { self.cells = cells self.table = table self.position = position } - /** - Access content of all cells in row or sets a content of a subsection of cells. + /// Access and modifier for a specific cell in a given row + public subscript(column: Int) -> PDFTableCell { + get { + cells[column] + } + set { + cells[column] = newValue + table.cells[position][column] = newValue + } + } - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + /** + * Access content of all cells in all rows or sets the content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var content: [PDFTableContentable?] { get { @@ -44,7 +61,9 @@ public class PDFTableRow { } /** - Setter method to change the content of all cells in the row + * Setter method to change the content of all cells in the row + * + * - Note: This method can not be used to get contents, because the type can only be a single value. */ public var allCellsContent: PDFTableContent? { @available(*, unavailable) @@ -52,14 +71,14 @@ public class PDFTableRow { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.content = newValue }) + cells.forEach { $0.content = newValue } } } /** - Access content of all cells in row or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in row or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var style: [PDFTableCellStyle?] { get { @@ -74,7 +93,9 @@ public class PDFTableRow { } /** - Setter method to change the style of all cells in the row + * Setter method to change the style of all cells in the row + * + * - Note: This method can not be used to get styles, because the type can only be a single value. */ public var allCellsStyle: PDFTableCellStyle? { @available(*, unavailable) @@ -82,14 +103,14 @@ public class PDFTableRow { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.style = newValue }) + cells.forEach { $0.style = newValue } } } /** - Access content of all cells in row or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access alignment of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting values, an assertion error will be thrown. */ public var alignment: [PDFTableCellAlignment] { get { @@ -104,7 +125,9 @@ public class PDFTableRow { } /** - Setter method to change the content of all cells in the row + * Setter method to change the style of all cells in the rows + * + * - Note: This method can not be used to get alignments, because the type can only be a single value. */ public var allCellsAlignment: PDFTableCellAlignment { @available(*, unavailable) @@ -112,24 +135,25 @@ public class PDFTableRow { fatalError("You cannot read from this object.") } set { - cells.forEach({ $0.alignment = newValue }) + cells.forEach { $0.alignment = newValue } } } } -extension PDFTableRow: PDFTableMergable { +// MARK: PDFTableMergable +extension PDFTableRow: PDFTableMergable { /// nodoc public func merge() { - self.merge(with: nil) + merge(with: nil) } /** - Merges all cells by replacing them with the same reference. - - If no parameter `cell` is given, the first cell in the first row will be used. - - - parameter cell: Cell to use after merge, may be nil + * Merges all cells by replacing them with the same reference. + * + * If no parameter `cell` is given, the first cell in the first row will be used. + * + * - Parameter cell: Cell to use after merge, may be nil */ public func merge(with cell: PDFTableCell? = nil) { table.cells[position] = Array(repeating: cell ?? table.cells[position][0], count: table.size.columns) diff --git a/Source/API/Table/Sections/PDFTableRows.swift b/Source/API/Table/Sections/PDFTableRows.swift index de9c9009..a689e76c 100644 --- a/Source/API/Table/Sections/PDFTableRows.swift +++ b/Source/API/Table/Sections/PDFTableRows.swift @@ -7,29 +7,35 @@ import Foundation -/** - References to multiple rows of a `PDFTable` - */ +/// References to multiple rows (``PDFTableRow``) of a ``PDFTable`` public class PDFTableRows { - - /** - List of row references - */ + /// Array of references to ``PDFTableRow`` public let rows: [PDFTableRow] + /// Reference to the ``PDFTable`` private let table: PDFTable + + /// Range of rows in the ``PDFTableRows/table`` private let range: Range - internal init(rows: [PDFTableRow], of table: PDFTable, in range: Range) { + /** + * Creates a new reference to multiple rows in a table. + * + * - Parameters: + * - rows: See ``PDFTableRows/rows`` for details + * - table: See ``PDFTableRows/table`` for details + * - range: See ``PDFTableRows/range`` for details + */ + init(rows: [PDFTableRow], of table: PDFTable, in range: Range) { self.rows = rows self.table = table self.range = range } /** - Access content of all cells in all rows or sets the content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in all rows or sets the content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var content: [[PDFTableContentable?]] { get { @@ -37,14 +43,16 @@ public class PDFTableRows { } set { assert(newValue.count <= rows.count, "Can not access more rows than available") - rows.enumerated().forEach { (rowIdx, row) in + for (rowIdx, row) in rows.enumerated() { row.content = newValue[rowIdx] } } } /** - Setter method to change the content of all rows to the same + * Setter method to change the content of all rows to the same + * + * - Note: This method can not be used to get contents, because the type can only be a single value per row. */ public var allRowsContent: [PDFTableContent?] { @available(*, unavailable) @@ -57,7 +65,9 @@ public class PDFTableRows { } /** - Setter method to change the content of all cells in the row + * Setter method to change the content of all cells in the row + * + * - Note: This method can not be used to get contents, because the type can only be a single value. */ public var allCellsContent: PDFTableContent? { @available(*, unavailable) @@ -70,9 +80,9 @@ public class PDFTableRows { } /** - Access style of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access style of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var style: [[PDFTableCellStyle?]] { get { @@ -80,14 +90,16 @@ public class PDFTableRows { } set { assert(newValue.count <= rows.count, "Can not access more rows than available") - rows.enumerated().forEach { (rowIdx, row) in + for (rowIdx, row) in rows.enumerated() { row.style = newValue[rowIdx] } } } /** - Setter method to change the style of all rows to the same + * Setter method to change the style of all cells in the row + * + * - Note: This method can not be used to get styles, because the type can only be a single value per row */ public var allRowsStyle: [PDFTableCellStyle?] { @available(*, unavailable) @@ -100,7 +112,9 @@ public class PDFTableRows { } /** - Setter method to change the style of all cells in the row + * Setter method to change the style of all cells in the row + * + * - Note: This method can not be used to get styles, because the type can only be a single value. */ public var allCellsStyle: PDFTableCellStyle? { @available(*, unavailable) @@ -113,9 +127,9 @@ public class PDFTableRows { } /** - Access alignment of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting values, an assertion error will be thrown. + * Access alignment of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting values, an assertion error will be thrown. */ public var alignment: [[PDFTableCellAlignment]] { get { @@ -123,16 +137,16 @@ public class PDFTableRows { } set { assert(newValue.count <= rows.count, "Can not access more rows than available") - rows.enumerated().forEach { (rowIdx, row) in + for (rowIdx, row) in rows.enumerated() { row.alignment = newValue[rowIdx] } } } /** - Sets the same alignment for each row - - If the bounds of the section is exceeded, an assertion error will be thrown. + * Setter method to change the style of all cells in the rows + * + * - Note: This method can not be used to get alignment, because the type can only be a single value per row */ public var allRowsAlignment: [PDFTableCellAlignment] { @available(*, unavailable) @@ -140,15 +154,17 @@ public class PDFTableRows { fatalError("You cannot read from this object.") } set { - rows.forEach { - assert(newValue.count <= $0.cells.count, "Can not access more columns than available") - $0.alignment = newValue + for row in rows { + assert(newValue.count <= row.cells.count, "Can not access more rows than available") + row.alignment = newValue } } } /** - Setter method to change the style of all cells in the rows + * Setter method to change the style of all cells in the rows + * + * - Note: This method can not be used to get alignments, because the type can only be a single value. */ public var allCellsAlignment: PDFTableCellAlignment { @available(*, unavailable) @@ -161,19 +177,20 @@ public class PDFTableRows { } } -extension PDFTableRows: PDFTableMergable { +// MARK: PDFTableMergable +extension PDFTableRows: PDFTableMergable { /// nodoc public func merge() { - self.merge(with: nil) + merge(with: nil) } /** - Merges all cells by replacing them with the same reference. - - If no parameter `cell` is given, the first cell in the first row will be used. - - - parameter cell: Cell to use after merge, may be nil + * Merges all cells by replacing them with the same reference. + * + * If no parameter `cell` is given, the first cell in the first row will be used. + * + * - Parameter cell: Cell to use after merge, may be nil */ public func merge(with cell: PDFTableCell? = nil) { for row in rows { diff --git a/Source/API/Table/Sections/PDFTableSection.swift b/Source/API/Table/Sections/PDFTableSection.swift index 1c4905c8..c99a1a82 100644 --- a/Source/API/Table/Sections/PDFTableSection.swift +++ b/Source/API/Table/Sections/PDFTableSection.swift @@ -7,21 +7,16 @@ import Foundation -/** - Reference to multiple rows and columns in a `PDFTable` - */ +/// Reference to a range of cells in a ``PDFTable`` public class PDFTableSection { - - /** - References to cells in these rows and columns - */ + /// References to cells in the ``PDFTable`` public let cells: [[PDFTableCell]] private let table: PDFTable private let rowsRange: Range private let columnsRange: Range - internal init(cells: [[PDFTableCell]], of table: PDFTable, in rowsRange: Range, and columnsRange: Range) { + init(cells: [[PDFTableCell]], of table: PDFTable, in rowsRange: Range, and columnsRange: Range) { self.cells = cells self.table = table self.rowsRange = rowsRange @@ -29,15 +24,15 @@ public class PDFTableSection { } /** - Access content of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access content of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var content: [[PDFTableContent?]] { get { - cells.map({ row in + cells.map { row in row.map(\.content) - }) + } } set { assert(newValue.count <= cells.count, "Can not access more rows than available") @@ -51,7 +46,9 @@ public class PDFTableSection { } /** - Setter method to change the style of all rows to the same + * Setter method to change the content of all rows to the same + * + * - Note: This method can not be used to get contents, because the type can only be a single value per row. */ public var allRowsContent: [PDFTableContent?] { @available(*, unavailable) @@ -69,7 +66,9 @@ public class PDFTableSection { } /** - Setter method to change the style of all rows to the same + * Setter method to change the content of all cells in the column + * + * - Note: This method can not be used to get contents, because the type can only be a single value per column. */ public var allColumnsContent: [PDFTableContent?] { @available(*, unavailable) @@ -87,7 +86,9 @@ public class PDFTableSection { } /** - Setter method to change the style of all rows to the same + * Setter method to change the content of all cells in the section + * + * - Note: This method can not be used to get contents, because the type can only be a single value. */ public var allCellsContent: PDFTableContent? { @available(*, unavailable) @@ -95,8 +96,8 @@ public class PDFTableSection { fatalError("You cannot read from this object.") } set { - cells.forEach { row in - row.forEach { cell in + for row in cells { + for cell in row { cell.content = newValue } } @@ -104,15 +105,15 @@ public class PDFTableSection { } /** - Access style of all cells in section or sets a content of a subsection of cells. - - If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. + * Access style of all cells in section or sets a content of a subsection of cells. + * + * If the bounds of the section is exceeded, when setting new values, an assertion error will be thrown. */ public var style: [[PDFTableCellStyle?]] { get { - cells.map({ row in + cells.map { row in row.map(\.style) - }) + } } set { assert(newValue.count <= cells.count, "Can not access more rows than available") @@ -126,7 +127,9 @@ public class PDFTableSection { } /** - Setter method to change the style of all rows to the same + * Setter method to change the style of all cells in the row + * + * - Note: This method can not be used to get styles, because the type can only be a single value per row */ public var allRowsStyle: [PDFTableCellStyle?] { @available(*, unavailable) @@ -135,16 +138,18 @@ public class PDFTableSection { } set { assert(newValue.count <= columnsRange.count, "Can not access more columns than available") - cells.forEach({ row in + for row in cells { for colIdx in 0.. Bool { guard lhs.left == rhs.left else { return false } guard lhs.top == rhs.top else { return false } @@ -47,6 +53,7 @@ public struct PDFTableCellBorders: Hashable { // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(left) hasher.combine(top) @@ -57,8 +64,7 @@ public struct PDFTableCellBorders: Hashable { // MARK: - Defaults -extension PDFTableCellBorders { - - public static let none = PDFTableCellBorders(left: .none, top: .none, right: .none, bottom: .none) - +public extension PDFTableCellBorders { + /// Convenience configuration for not displaying any cell border + static let none = PDFTableCellBorders(left: .none, top: .none, right: .none, bottom: .none) } diff --git a/Source/API/Table/Style/PDFTableCellPosition+Equatable-Hashable.swift b/Source/API/Table/Style/PDFTableCellPosition+Equatable-Hashable.swift index cf5b2a83..aa94192f 100644 --- a/Source/API/Table/Style/PDFTableCellPosition+Equatable-Hashable.swift +++ b/Source/API/Table/Style/PDFTableCellPosition+Equatable-Hashable.swift @@ -7,38 +7,20 @@ import Foundation -/** - TODO: Documentation - */ -extension PDFTableCellPosition: Hashable { - - /** - Creates a hash value. +// MARK: - PDFTableCellPosition + Hashable - Hash values are not guaranteed to be equal across different executions of - your program. Do not save hash values to use during a future execution. - */ +extension PDFTableCellPosition: Hashable { + /// Creates a hash value of the cell position public func hash(into hasher: inout Hasher) { hasher.combine(row) hasher.combine(column) } } -/** - TODO: Documentation - */ -extension PDFTableCellPosition: Equatable { +// MARK: - PDFTableCellPosition + Equatable - /** - Returns a Boolean value indicating whether two values are equal. - - Equality is the inverse of inequality. For any values `a` and `b`, - `a == b` implies that `a != b` is `false`. - - - Parameters: - - lhs: A value to compare. - - rhs: Another value to compare. - */ +extension PDFTableCellPosition: Equatable { + /// nodoc public static func == (lhs: PDFTableCellPosition, rhs: PDFTableCellPosition) -> Bool { guard lhs.row == rhs.row else { return false diff --git a/Source/API/Table/Style/PDFTableCellStyle.swift b/Source/API/Table/Style/PDFTableCellStyle.swift index 78a87a80..ff351ad3 100644 --- a/Source/API/Table/Style/PDFTableCellStyle.swift +++ b/Source/API/Table/Style/PDFTableCellStyle.swift @@ -6,37 +6,35 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ +/// Structure used to manage the custom style of a ``PDFTableCell`` public struct PDFTableCellStyle: Hashable { - - /** - TODO: Documentation - */ + /// The cell fill (background) color and the text color public var colors: (fill: Color, text: Color) - /** - TODO: Documentation - */ + /// Custom border styling (see ``PDFTableCellBorders`` for details) public var borders: PDFTableCellBorders - /** - TODO: Documentation - */ + /// Font used for text content in cells public var font: Font /** - TODO: Documentation + * Creates a new cell style + * + * - Parameters: + * - colors: See ``PDFTableCellStyle/colors`` + * - borders: See ``PDFTableCellStyle/borders`` + * - font: See ``PDFTableCellStyle/font`` */ - public init(colors: (fill: Color, text: Color) = (Color.clear, Color.black), - borders: PDFTableCellBorders = PDFTableCellBorders(), - font: Font = Font.systemFont(ofSize: PDFConstants.defaultFontSize)) { + public init( + colors: (fill: Color, text: Color) = (Color.clear, Color.black), + borders: PDFTableCellBorders = PDFTableCellBorders(), + font: Font = Font.systemFont(ofSize: PDFConstants.defaultFontSize) + ) { self.colors = colors self.borders = borders self.font = font @@ -44,6 +42,7 @@ public struct PDFTableCellStyle: Hashable { // MARK: - Equatable + /// nodoc public static func == (lhs: PDFTableCellStyle, rhs: PDFTableCellStyle) -> Bool { guard lhs.colors == rhs.colors else { return false @@ -56,8 +55,10 @@ public struct PDFTableCellStyle: Hashable { } return true } + // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(colors.fill) hasher.combine(colors.text) @@ -66,9 +67,11 @@ public struct PDFTableCellStyle: Hashable { } } -extension PDFTableCellStyle { - - public static let none = PDFTableCellStyle(colors: (fill: Color.clear, text: Color.black), - borders: .none, - font: Font.systemFont(ofSize: PDFConstants.defaultFontSize)) +public extension PDFTableCellStyle { + /// Default cell style not displaying any background or borders + static let none = PDFTableCellStyle( + colors: (fill: Color.clear, text: Color.black), + borders: .none, + font: Font.systemFont(ofSize: PDFConstants.defaultFontSize) + ) } diff --git a/Source/API/Table/Style/PDFTableStyle+Defaults.swift b/Source/API/Table/Style/PDFTableStyle+Defaults.swift index 5848ac87..49b1c138 100644 --- a/Source/API/Table/Style/PDFTableStyle+Defaults.swift +++ b/Source/API/Table/Style/PDFTableStyle+Defaults.swift @@ -6,25 +6,22 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - A collection of table style defaults - */ +/// A collection of commonly used ``PDFTableStyle public enum PDFTableStyleDefaults { - /** - None: - - - No header rows - - No header columns - - No footer row - - No alternating rows - - Simple outline - - Simple borders + * None: + * + * - No header rows + * - No header columns + * - No footer row + * - No alternating rows + * - Simple outline + * - Simple borders */ public static var none: PDFTableStyle { PDFTableStyle( @@ -40,20 +37,23 @@ public enum PDFTableStyleDefaults { left: PDFLineStyle(type: .full, color: .black, width: 1), top: PDFLineStyle(type: .full, color: .black, width: 1), right: PDFLineStyle(type: .full, color: .black, width: 1), - bottom: PDFLineStyle(type: .full, color: .black, width: 1))), - alternatingContentStyle: nil) + bottom: PDFLineStyle(type: .full, color: .black, width: 1) + )), + alternatingContentStyle: nil + ) } - /** - Simple table: - - One header row - - One header column - - Row Header: - - Text color white - - No border, only light gray border at bottom - - Column Header: - - Bold font - - Alternating content rows + /** + * Simple table: + * + * - One header row + * - One header column + * - Row Header: + * - Text color white + * - No border, only light gray border at bottom + * - Column Header: + * - Bold font + * - Alternating content rows */ public static var simple: PDFTableStyle { let darkGray = Color(red: 59.0 / 255.0, green: 59.0 / 255.0, blue: 59.0 / 255.0, alpha: 1.0) diff --git a/Source/API/Table/Style/PDFTableStyle+Equatable.swift b/Source/API/Table/Style/PDFTableStyle+Equatable.swift index 445526f7..9447727f 100644 --- a/Source/API/Table/Style/PDFTableStyle+Equatable.swift +++ b/Source/API/Table/Style/PDFTableStyle+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 09/11/2017. // -/** - TODO: Documentation - */ extension PDFTableStyle: Equatable { - - /** - TODO: Documentation - */ + /// nodoc public static func == (lhs: PDFTableStyle, rhs: PDFTableStyle) -> Bool { guard lhs.rowHeaderCount == rhs.rowHeaderCount else { return false @@ -43,5 +37,4 @@ extension PDFTableStyle: Equatable { } return true } - } diff --git a/Source/API/Table/Style/PDFTableStyle.swift b/Source/API/Table/Style/PDFTableStyle.swift index 4bcefd3e..7e779ae1 100644 --- a/Source/API/Table/Style/PDFTableStyle.swift +++ b/Source/API/Table/Style/PDFTableStyle.swift @@ -6,81 +6,70 @@ // /** - TODO: Documentation + * Structure used to manage the styling of a ``PDFTable`` + * + * The styling of a ``PDFTable`` can be defined by setting the property ``PDFTable/style`` */ public class PDFTableStyle { - - /** - TODO: Documentation - */ + /// Count of rows which will use the style configured in ``rowHeaderStyle`` public var rowHeaderCount: Int - /** - TODO: Documentation - */ + /// Count of columns which will use the style configured in ``columnHeaderStyle`` public var columnHeaderCount: Int - /** - TODO: Documentation - */ + /// Count of footers which will use the style configured in ``footerStyle`` public var footerCount: Int - /** - TODO: Documentation - */ + /// Style used for the outer border public var outline: PDFLineStyle - /** - The cell style of row headers. Horizontal border lines are ignored, as these are defined in - */ + /// Style of cells in the header rows public var rowHeaderStyle: PDFTableCellStyle - /** - TODO: Documentation - */ + /// Style of cells in the header columns public var columnHeaderStyle: PDFTableCellStyle - /** - TODO: Documentation - */ + /// Style of cells in the footer rows public var footerStyle: PDFTableCellStyle - /** - TODO: Documentation - */ + /// Style of cells without special purpose public var contentStyle: PDFTableCellStyle /** - TODO: Documentation + * Style used for alternating content rows + * + * Setting this property will enable alternating row styling, which will apply this style to every other row */ public var alternatingContentStyle: PDFTableCellStyle? /** - Create a table style. All parameters are optional - - - Parameters: - - rowHeaderCount: Number of top rows which have header style, defaults to `1` - - columnHeaderCount: Number of left columns with header style, defaults to `1` - - footerCount: Number of footer rows with header style, defaults to `1` - - outline: Line style of the outer borderlines, defaults to `TablePDFLineStyle.init` - - showHorizontalGridLines: Render horizontal grid lines, defaults to `true` - - showVerticalGridLines: Render vertical grid lines, defaults to `true` - - showRowHeaderGridLines: Render row header grid lines, defaults to `true` - - showColumnHeaderGridLines: Render column header grid lines, defaults to `true` - - showFooterGridLines: Render footer grid lines, defaults to `true` - - rowHeaderStyle: The cell style of row header cells, defaults to `TablePDFLineStyle.init` - - columnHeaderStyle: The cell style of row header cells, defaults to `TablePDFLineStyle.init` - - footerStyle: The cell style of row header cells, defaults to `TablePDFLineStyle.init` + * Create a table style + * + * - Parameters: + * - rowHeaderCount: Number of top rows which have header style + * - columnHeaderCount: Number of left columns with header style + * - footerCount: Number of footer rows with header style + * - outline: Line style of the outer borderlines + * - showHorizontalGridLines: Render horizontal grid lines + * - showVerticalGridLines: Render vertical grid lines + * - showRowHeaderGridLines: Render row header grid lines + * - showColumnHeaderGridLines: Render column header grid lines + * - showFooterGridLines: Render footer grid lines + * - rowHeaderStyle: The cell style of row header cells + * - columnHeaderStyle: The cell style of row header cells + * - footerStyle: The cell style of row header cells */ - public init(rowHeaderCount: Int = 1, - columnHeaderCount: Int = 1, - footerCount: Int = 1, - outline: PDFLineStyle = PDFLineStyle(), - rowHeaderStyle: PDFTableCellStyle = PDFTableCellStyle(), - columnHeaderStyle: PDFTableCellStyle = PDFTableCellStyle(), - footerStyle: PDFTableCellStyle = PDFTableCellStyle(), - contentStyle: PDFTableCellStyle = PDFTableCellStyle(), - alternatingContentStyle: PDFTableCellStyle? = nil) { + public init( + rowHeaderCount: Int = 1, + columnHeaderCount: Int = 1, + footerCount: Int = 1, + outline: PDFLineStyle = PDFLineStyle(), + rowHeaderStyle: PDFTableCellStyle = PDFTableCellStyle(), + columnHeaderStyle: PDFTableCellStyle = PDFTableCellStyle(), + footerStyle: PDFTableCellStyle = PDFTableCellStyle(), + contentStyle: PDFTableCellStyle = PDFTableCellStyle(), + alternatingContentStyle: PDFTableCellStyle? = nil + ) { self.rowHeaderCount = rowHeaderCount self.columnHeaderCount = columnHeaderCount self.footerCount = footerCount @@ -94,21 +83,18 @@ public class PDFTableStyle { self.alternatingContentStyle = alternatingContentStyle } - /** - Creates a identical copy of this style - */ + /// nodoc public func copy() -> PDFTableStyle { PDFTableStyle( - rowHeaderCount: self.rowHeaderCount, - columnHeaderCount: self.columnHeaderCount, - footerCount: self.footerCount, - outline: self.outline, - rowHeaderStyle: self.rowHeaderStyle, - columnHeaderStyle: self.columnHeaderStyle, - footerStyle: self.footerStyle, - contentStyle: self.contentStyle, - alternatingContentStyle: self.alternatingContentStyle + rowHeaderCount: rowHeaderCount, + columnHeaderCount: columnHeaderCount, + footerCount: footerCount, + outline: outline, + rowHeaderStyle: rowHeaderStyle, + columnHeaderStyle: columnHeaderStyle, + footerStyle: footerStyle, + contentStyle: contentStyle, + alternatingContentStyle: alternatingContentStyle ) } - } diff --git a/Source/API/Text/PDFAttributedText.swift b/Source/API/Text/PDFAttributedText.swift index 234c8b5f..213a0011 100644 --- a/Source/API/Text/PDFAttributedText.swift +++ b/Source/API/Text/PDFAttributedText.swift @@ -5,48 +5,49 @@ // Created by Philip Niedertscheider on 31/10/2017. // +import Foundation + #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Attributed text objects hold an instance of `NSAttributedString` - - Use this class for advanced text drawing + * Advanced text objects using an attributed string``Foundation.NSAttributedString`` as the internal structure. + * + * Use this class for advanced text drawing. + * For simpler use cases, consider ``PDFSimpleText``. */ public class PDFAttributedText: PDFText { - - /** - Text which will be drawn - */ + /// Attributed string which will be drawn in the PDF graphics context public var text: NSAttributedString /** - Initializer - - - parameter text: Text, which will be drawn + * Creates a new attributed text object with the given `text` + * + * - Parameter text: ``Foundation.NSAttributedString`` to be drawn in the document */ public init(text: NSAttributedString) { self.text = text } - /** - Creats a new `PDFAttributedText` with the same properties - */ + /// Creates a new ``PDFAttributedText`` with the same properties override public var copy: PDFText { PDFAttributedText(text: text) } // MARK: - Equatable - /// Compares two instances of `PDFAttributedText` for equality - /// - /// - Parameters: - /// - lhs: One instance of `PDFAttributedText` - /// - rhs: Another instance of `PDFAttributedText` - /// - Returns: `true`, if `attributes`, `tag` and `text` equal; otherwise `false` + /** + * Compares two instances of `PDFAttributedText` for equality + * + * - Parameters: + * - lhs: One instance of `PDFAttributedText` + * - rhs: Another instance of `PDFAttributedText` + * + * - Returns: `true`, if `text` equal; otherwise `false` + */ override public func isEqual(to other: PDFDocumentObject) -> Bool { guard super.isEqual(to: other) else { return false @@ -54,7 +55,7 @@ public class PDFAttributedText: PDFText { guard let otherAttributedText = other as? PDFAttributedText else { return false } - guard self.text == otherAttributedText.text else { + guard text == otherAttributedText.text else { return false } return true @@ -62,6 +63,7 @@ public class PDFAttributedText: PDFText { // MARK: - Hashable + /// nodoc override public func hash(into hasher: inout Hasher) { hasher.combine(text) } diff --git a/Source/API/Text/PDFSimpleText+Equatable.swift b/Source/API/Text/PDFSimpleText+Equatable.swift index 2348e64a..760111ee 100644 --- a/Source/API/Text/PDFSimpleText+Equatable.swift +++ b/Source/API/Text/PDFSimpleText+Equatable.swift @@ -5,26 +5,9 @@ // Created by Philip Niedertscheider on 09/11/2017. // -/** - TODO: Documentation - */ -extension PDFSimpleText { - - public static func == (lhs: PDFSimpleText, rhs: PDFSimpleText) -> Bool { - // Properties of PDFObjectAttribute - guard lhs.attributes == rhs.attributes else { - return false - } - guard lhs.tag == rhs.tag else { - return false - } - // Properties of PDFSimpleText - guard lhs.text == rhs.text else { - return false - } - guard lhs.spacing == rhs.spacing else { - return false - } - return true +public extension PDFSimpleText { + /// nodoc + static func == (lhs: PDFSimpleText, rhs: PDFSimpleText) -> Bool { + lhs.isEqual(to: rhs) } } diff --git a/Source/API/Text/PDFSimpleText.swift b/Source/API/Text/PDFSimpleText.swift index 1d3f4cfd..17503b12 100644 --- a/Source/API/Text/PDFSimpleText.swift +++ b/Source/API/Text/PDFSimpleText.swift @@ -6,39 +6,37 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Text and spacing of a text object. - - Use this class for simple and quick text drawing + * Plain text object with basic styling. + * + * The text of a ``PDFSimpleText`` will be styled using either the referenced ``PDFTextStyle`` set on `style`, or otherwise using the + * styling of the parent container. + * + * Use this class for simple text drawing. + * For advanced use cases see ``PDFAttributedText``. */ public class PDFSimpleText: PDFText { - - /** - Text to be drawn - */ + /// Text to be drawn public var text: String - /** - Line spacing if multiple lines - */ + //// Line spacing if multiple lines public var spacing: CGFloat - /** - Weak reference to style used by this text object - */ + /// Weak reference to style used by this text object public weak var style: PDFTextStyle? /** - Initializer - - - parameter text: Text to be drawn - - parameter spacing: Spacing between text lines, defaults to 0 - - parameter style: Reference to style, defaults to nil + * Creates a new simple text object + * + * - Parameters: + * - text: Text to be drawn + * - spacing: Spacing between text lines, defaults to `0` + * - style: Reference to ``PDFTextStyle``, defaults to `nil` */ public init(text: String, spacing: CGFloat = 0, style: PDFTextStyle? = nil) { self.text = text @@ -46,20 +44,14 @@ public class PDFSimpleText: PDFText { self.style = style } - /** - Creates a new `PDFSimpleText` with the same properties - */ + /// Creates a new `PDFSimpleText` with the same properties override public var copy: PDFText { - PDFSimpleText(text: self.text, spacing: self.spacing, style: self.style) + PDFSimpleText(text: text, spacing: spacing, style: style) } // MARK: - Equatable - /// Compares two instances of `PDFSimpleText` for equality - /// - /// - Parameters: - /// - other: Another instance of `PDFSimpleText` - /// - Returns: `true`, if `attributes`, `tag`, `text` and `spacing` equal; otherwise `false` + /// nodoc override public func isEqual(to other: PDFDocumentObject) -> Bool { guard super.isEqual(to: other) else { return false @@ -67,13 +59,13 @@ public class PDFSimpleText: PDFText { guard let otherText = other as? PDFSimpleText else { return false } - guard self.text == otherText.text else { + guard text == otherText.text else { return false } - guard self.spacing == otherText.spacing else { + guard spacing == otherText.spacing else { return false } - guard self.style == otherText.style else { + guard style == otherText.style else { return false } return true @@ -81,6 +73,7 @@ public class PDFSimpleText: PDFText { // MARK: - Hashable + /// nodoc override public func hash(into hasher: inout Hasher) { hasher.combine(text) hasher.combine(spacing) diff --git a/Source/API/Text/PDFText.swift b/Source/API/Text/PDFText.swift index 4ab1dee9..cceadf92 100644 --- a/Source/API/Text/PDFText.swift +++ b/Source/API/Text/PDFText.swift @@ -5,10 +5,12 @@ // Created by Philip Niedertscheider on 31/10/2017. // -/// Protocol all text objects should implement +/// Abstract class all text objects should implement public class PDFText: PDFDocumentObject, CustomStringConvertible { - + /// Creates a new copy of this text + /// + /// - Note: Must be implemented by all subclasses public var copy: PDFText { - fatalError() + fatalError("Not implemented") } } diff --git a/Source/API/Text/PDFTextStyle.swift b/Source/API/Text/PDFTextStyle.swift index dd67ccd6..2a36abba 100644 --- a/Source/API/Text/PDFTextStyle.swift +++ b/Source/API/Text/PDFTextStyle.swift @@ -6,37 +6,39 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - TODO: Documentation + * Structure to combine multiple aspects of text styling. + * + * Used to define text styling configuration in a global context. + * + * Furthermore, styles of a ``PDFDocument`` should be used to select headers for a ``PDFTableOfContent``. + * See ``PDFTableOfContent`` for details. */ public class PDFTextStyle: Hashable { - - /** - Name of style - */ + /// Name of style public var name: String - /** - Font of object - */ + /// Font of the text public var font: Font? - /** - Text color of object - */ + /// Color of the text public var color: Color? /** - Initializer - - - parameter name: Name of style - - parameter font: Font of text, defaults to nil - - parameter color: Color of text, defaults to nil + * Creates a new style with the given parameters. + * + * By setting all parameters to `nil` (except `name`, which is required) the style can be used only to detect text objects + * for the ``PDFTableOfContent``, without actually affecting the styling of the text. + * + * - Parameters: + * - name: Name of style + * - font: Font of text, defaults to `nil` + * - color: Color of text, defaults to `nil` */ public init(name: String, font: Font? = nil, color: Color? = nil) { self.name = name @@ -46,6 +48,7 @@ public class PDFTextStyle: Hashable { // MARK: - Equatable + /// nodoc public static func == (lhs: PDFTextStyle, rhs: PDFTextStyle) -> Bool { guard lhs.name == rhs.name else { return false @@ -61,6 +64,7 @@ public class PDFTextStyle: Hashable { // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(name) hasher.combine(font) diff --git a/Source/API/Utils/CrossPlattformGraphics.swift b/Source/API/Utils/CrossPlattformGraphics.swift index 8ca277cf..632524b3 100644 --- a/Source/API/Utils/CrossPlattformGraphics.swift +++ b/Source/API/Utils/CrossPlattformGraphics.swift @@ -1,233 +1,260 @@ // // CrossPlattformGraphics.swift // +// This file contains convenience types to support cross-plattform usage on iOS and macOS // // Created by Philip Niedertscheider on 19.05.20. // #if os(iOS) - -import UIKit - -public typealias Color = UIColor -public typealias Font = UIFont -public typealias Image = UIImage -public typealias EdgeInsets = UIEdgeInsets -public typealias BezierPath = UIBezierPath -public typealias Point = CGPoint -public typealias RectCorner = UIRectCorner + import UIKit + + /// Cross-plattform type for `UIColor` and `NSColor` + public typealias Color = UIColor + /// Cross-plattform type for `UIFont` and `NSFont` + public typealias Font = UIFont + /// Cross-plattform type for `UIImage` and `NSImage` + public typealias Image = UIImage + /// Cross-plattform type for `UIEdgeInsets` and `NSEdgeInsets` + public typealias EdgeInsets = UIEdgeInsets + /// Cross-plattform type for `UIBezierPath` and `NSBezierPath` + public typealias BezierPath = UIBezierPath + /// Cross-plattform type for `CGPoint` and `NSPoint` + public typealias Point = CGPoint + /// Cross-plattform type for `UIRectCorner` and `RectCorner` + public typealias RectCorner = UIRectCorner #elseif os(macOS) -import AppKit - -public typealias Color = NSColor -public typealias Font = NSFont -public typealias Image = NSImage -public typealias EdgeInsets = NSEdgeInsets -public typealias BezierPath = NSBezierPath -public typealias Point = NSPoint - -extension NSBezierPath { - func quadCurve(to endPoint: CGPoint, controlPoint: CGPoint) { - let startPoint = self.currentPoint - let controlPoint1 = CGPoint(x: (startPoint.x + (controlPoint.x - startPoint.x) * 2.0/3.0), - y: (startPoint.y + (controlPoint.y - startPoint.y) * 2.0/3.0)) - let controlPoint2 = CGPoint(x: (endPoint.x + (controlPoint.x - endPoint.x) * 2.0/3.0), - y: (endPoint.y + (controlPoint.y - endPoint.y) * 2.0/3.0)) - curve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2) + import AppKit + + /// Cross-plattform type for `UIColor` and `NSColor` + public typealias Color = NSColor + /// Cross-plattform type for `UIFont` and `NSFont` + public typealias Font = NSFont + /// Cross-plattform type for `UIImage` and `NSImage` + public typealias Image = NSImage + /// Cross-plattform type for `UIEdgeInsets` and `NSEdgeInsets` + public typealias EdgeInsets = NSEdgeInsets + /// Cross-plattform type for `UIBezierPath` and `NSBezierPath` + public typealias BezierPath = NSBezierPath + /// Cross-plattform type for `CGPoint` and `NSPoint` + public typealias Point = NSPoint + + extension NSBezierPath { + /** + * Extends the built-in functionality with a quad-curve operator, to match the implemenation of `UIBezierPath` + */ + func quadCurve(to endPoint: CGPoint, controlPoint: CGPoint) { + let startPoint = currentPoint + let controlPoint1 = CGPoint( + x: startPoint.x + (controlPoint.x - startPoint.x) * 2.0 / 3.0, + y: startPoint.y + (controlPoint.y - startPoint.y) * 2.0 / 3.0 + ) + let controlPoint2 = CGPoint( + x: endPoint.x + (controlPoint.x - endPoint.x) * 2.0 / 3.0, + y: endPoint.y + (controlPoint.y - endPoint.y) * 2.0 / 3.0 + ) + curve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2) + } } -} - -extension NSEdgeInsets { - public static var zero: NSEdgeInsets { - NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) + public extension NSEdgeInsets { + /// An edge insets struct whose top, left, bottom, and right fields are all set to 0. + static var zero: NSEdgeInsets { + NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) + } } -} -extension NSEdgeInsets: Equatable { - - public static func == (lhs: NSEdgeInsets, rhs: NSEdgeInsets) -> Bool { - lhs.top == rhs.top && lhs.left == rhs.left && lhs.bottom == rhs.bottom && lhs.right == rhs.right + extension NSEdgeInsets: Equatable { + public static func == (lhs: NSEdgeInsets, rhs: NSEdgeInsets) -> Bool { + lhs.top == rhs.top && lhs.left == rhs.left && lhs.bottom == rhs.bottom && lhs.right == rhs.right + } } -} -public struct RectCorner: OptionSet { + public struct RectCorner: OptionSet { + public static var topLeft: RectCorner = .init(rawValue: 1 << 0) + public static var topRight: RectCorner = .init(rawValue: 1 << 1) + public static var bottomLeft: RectCorner = .init(rawValue: 1 << 2) + public static var bottomRight: RectCorner = .init(rawValue: 1 << 3) + public static var allCorners: RectCorner = .init(rawValue: 1 << 4 - 1) - public static var topLeft: RectCorner = RectCorner(rawValue: 1 << 0) - public static var topRight: RectCorner = RectCorner(rawValue: 1 << 1) - public static var bottomLeft: RectCorner = RectCorner(rawValue: 1 << 2) - public static var bottomRight: RectCorner = RectCorner(rawValue: 1 << 3) - public static var allCorners: RectCorner = RectCorner(rawValue: 1 << 4 - 1) + let value: Int - let value: Int + public init(rawValue: Int) { + self.value = rawValue + } - public init(rawValue: Int) { - self.value = rawValue + public var rawValue: Int { + value + } } - public var rawValue: Int { - value - } -} - -extension CGRect { - - func inset(by inset: EdgeInsets) -> CGRect { - CGRect(x: self.minX + inset.left, - y: self.minY + inset.top, - width: self.width - inset.left - inset.right, - height: self.height - inset.top - inset.bottom) + extension CGRect { + func inset(by inset: EdgeInsets) -> CGRect { + CGRect(x: minX + inset.left, + y: minY + inset.top, + width: width - inset.left - inset.right, + height: height - inset.top - inset.bottom) + } } -} -extension NSBezierPath { - - var cgPath: CGPath { - let path = CGMutablePath() - var points = [CGPoint](repeating: .zero, count: 3) - for i in 0 ..< self.elementCount { - let type = self.element(at: i, associatedPoints: &points) - - switch type { - case .moveTo: - path.move(to: points[0]) - case .lineTo: - path.addLine(to: points[0]) - case .curveTo: - path.addCurve(to: points[2], control1: points[0], control2: points[1]) - case .closePath: - path.closeSubpath() - @unknown default: - break + extension NSBezierPath { + var cgPath: CGPath { + let path = CGMutablePath() + var points = [CGPoint](repeating: .zero, count: 3) + for i in 0.. Bool { lhs.isEqual(to: rhs) } + /// nodoc public func isEqual(to other: PDFDocumentObject) -> Bool { - guard self.attributes == other.attributes else { return false } - guard self.tag == other.tag else { return false } + guard attributes == other.attributes else { return false } + guard tag == other.tag else { return false } return true } // MARK: - Hashable + /// nodoc public func hash(into hasher: inout Hasher) { hasher.combine(attributes) hasher.combine(tag) diff --git a/Source/API/Utils/PDFError.swift b/Source/API/Utils/PDFError.swift index 3aac80ed..daf0835d 100644 --- a/Source/API/Utils/PDFError.swift +++ b/Source/API/Utils/PDFError.swift @@ -7,102 +7,60 @@ import Foundation -/** - List of errors which can occur during using this framework - */ +/// List of errors which can be thrown during configuration, calculations or rendering public enum PDFError: LocalizedError { - - /** - TODO: Documentation - */ + /// The associated `value` is an instance of an unsupported type. case tableContentInvalid(value: Any?) - /** - TODO: Documentation - */ + /// Indicates that a table without any data was added to the document, which is unsupported case tableIsEmpty - /** - TODO: Documentation - */ + /// The given table structure does not match, i.e. the data matrix size does not match the cell alignment configuration case tableStructureInvalid(message: String) - /** - TODO: Documentation - */ + /// Thrown when accessing a cell outside of the table bounds case tableIndexOutOfBounds(index: Int, length: Int) - /** - TODO: Documentation - */ - case tableCellWeakReferenceBroken - /// Indicates that the cell is too big to be rendered onto a single page case tableCellTooBig(cell: PDFTableCell) - /** - TODO: Documentation - */ + /// Thrown when neither a ``PDFSimpleText`` nor a ``UIKit/NSAttributedString`` is set in an ``PDFAttributedText`` case textObjectIsNil - /** - TODO: Documentation - */ + /// Thrown when a ``PDFAttributedText`` should be rendered without being calculated first case textObjectNotCalculated - /** - TODO: Documentation - */ - case invalidHexLength(length: Int) - - /** - TODO: Documentation - */ - case invalidHex(hex: String) - - /** - TODO: Documentation - */ + /// Thrown when copying of a PDF object fails case copyingFailed - /** - TODO: Documentation - */ + /// Thrown when an external PDF document could not be loaded from the given `url` case externalDocumentURLInvalid(url: URL) /// Index of page in external document is out of bounds case pageOutOfBounds(index: Int) - /** - TODO: Documentation - */ + /// nodoc public var errorDescription: String? { switch self { - case .tableContentInvalid(let value): + case let .tableContentInvalid(value): return "Table content is invalid: " + value.debugDescription case .tableIsEmpty: return "Table is empty" - case .tableStructureInvalid(let message): + case let .tableStructureInvalid(message): return "Table structure invalid: " + message - case .tableIndexOutOfBounds(let index, let length): + case let .tableIndexOutOfBounds(index, length): return "Table index out of bounds: " - case .tableCellWeakReferenceBroken: - return "Weak reference in table cell is broken" - case .tableCellTooBig(let cell): + case let .tableCellTooBig(cell): return "Table cell is too big to be rendered: \(cell)" case .textObjectIsNil: return "No text object has been set" case .textObjectNotCalculated: return "Text object is missing string, maybe not calculated?" - case .invalidHexLength(let length): - return "Hex color string has invalid length: \(length)" - case .invalidHex(let hex): - return "Invalid hexdecimal string: " + hex case .copyingFailed: return "Failed to create a copy of an object" - case .externalDocumentURLInvalid(let url): + case let .externalDocumentURLInvalid(url): return "Could not open PDF document at url: " + url.absoluteString - case .pageOutOfBounds(let index): + case let .pageOutOfBounds(index): return "Page \(index) in external document is out of bounds" } } diff --git a/Source/API/Utils/PDFRenderObject.swift b/Source/API/Utils/PDFRenderObject.swift index abf189ce..393eefff 100644 --- a/Source/API/Utils/PDFRenderObject.swift +++ b/Source/API/Utils/PDFRenderObject.swift @@ -6,69 +6,64 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - All renderable objects subclass from this object. - Each object is first calculated and then drawn. + * All renderable objects subclass from this object. + * + * Each object is first calculated and then drawn. */ public class PDFRenderObject: CustomStringConvertible { + /// Frame of this object + var frame: CGRect = .null - /** - Frame of this object - */ - internal var frame: CGRect = CGRect.null - - /** - Attributes set for this object, and their calculated frame - */ - internal var attributes: [(attribute: PDFObjectAttribute, frame: CGRect)] = [] + /// Attributes set for this object, and their calculated frame + var attributes: [(attribute: PDFObjectAttribute, frame: CGRect)] = [] /** - Calculates the object and returns all calculated objects which are created by this calculated. - - - parameter generator: - - parameter container: - - - throws: PDFError - - - returns: List of objects and the container they are located in + * Calculates the object and returns all calculated objects which are created by this calculated. + * + * - Parameter generator: + * - Parameter container: + * + * - Throws: PDFError + * + * - Returns: List of objects and the container they are located in */ @discardableResult - internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + func calculate(generator _: PDFGenerator, container _: PDFContainer) throws -> [PDFLocatedRenderObject] { [] } /** - Draws the object into the current graphics context. - - - parameter generator: Unused - - parameter container: Unused - - - throws: None + * Draws the object into the current graphics context. + * + * - Parameter generator: Unused + * - Parameter container: Unused + * + * - Throws: None */ - internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + func draw(generator _: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { applyAttributes(in: context) } - /** - TODO: Documentation - */ - internal var copy: PDFRenderObject { + /// nodoc + var copy: PDFRenderObject { fatalError() } /** - Applies the attributes to the current render context. - Should be called after calling `draw` + * Applies the attributes to the current render context. + * + * Should be called after calling `draw` */ - internal func applyAttributes(in context: PDFContext) { + func applyAttributes(in context: PDFContext) { for (attribute, frame) in attributes { switch attribute { - case .link(let url): + case let .link(url): context.setURL(url as CFURL, for: frame.applying(context.userSpaceToDeviceSpaceTransform)) } } diff --git a/Source/API/Utils/PDFTaggableObject.swift b/Source/API/Utils/PDFTaggableObject.swift index dbd5ab07..a0c8a222 100644 --- a/Source/API/Utils/PDFTaggableObject.swift +++ b/Source/API/Utils/PDFTaggableObject.swift @@ -3,15 +3,12 @@ // TPPDF // // Created by Philip Niedertscheider on 04.12.20. -// Copyright © 2020 Philip Niedertscheider. All rights reserved. // /// Object can be identified using the `tag` property public protocol PDFTaggableObject { - /// An integer that you can use to identify document objects in your application. /// /// The default value is 0. You can set the value of this tag and use that value to identify the object later. var tag: Int { get set } - } diff --git a/Source/Internal/External/PDFExternalDocumentObject.swift b/Source/Internal/External/PDFExternalDocumentObject.swift index 946431a9..aaf712e8 100644 --- a/Source/Internal/External/PDFExternalDocumentObject.swift +++ b/Source/Internal/External/PDFExternalDocumentObject.swift @@ -5,22 +5,31 @@ // Created by Philip Niedertscheider on 12.08.19. // -import Foundation import CoreGraphics +import Foundation -internal class PDFExternalDocumentObject: PDFRenderObject { - - internal var url: URL - internal var pages: [Int] +class PDFExternalDocumentObject: PDFRenderObject { + /// File URL to an external document + var url: URL + /// Array of page indicies which should be included from the external document + var pages: [Int] - internal init(url: URL, pages: [Int]) { + /** + * Creates a new instance for the given URL + * + * - Parameter url: File URL to an external document, see ``PDFExternalDocument/url`` + * - Parameter pages: Array of page indicies which should be included from the external document, see ``PDFExternalDocument/pages`` + */ + init(url: URL, pages: [Int]) { self.url = url self.pages = pages } - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] + // Load the PDF document from the defined file URL and split it into individual page objects guard let cgPDF = CGPDFDocument(url as CFURL) else { throw PDFError.externalDocumentURLInvalid(url: url) } @@ -35,10 +44,8 @@ internal class PDFExternalDocumentObject: PDFRenderObject { return result } - /** - TODO: documentation - */ - override internal var copy: PDFRenderObject { - PDFExternalDocumentObject(url: self.url, pages: self.pages) + /// nodoc + override var copy: PDFRenderObject { + PDFExternalDocumentObject(url: url, pages: pages) } } diff --git a/Source/Internal/External/PDFExternalPageObject.swift b/Source/Internal/External/PDFExternalPageObject.swift index 0e6680d4..3075f07e 100644 --- a/Source/Internal/External/PDFExternalPageObject.swift +++ b/Source/Internal/External/PDFExternalPageObject.swift @@ -6,27 +6,26 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -internal class PDFExternalPageObject: PDFRenderObject { +class PDFExternalPageObject: PDFRenderObject { + var page: CGPDFPage - internal var page: CGPDFPage - - internal init(page: CGPDFPage) { + init(page: CGPDFPage) { self.page = page } - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { - self.frame = page.getBoxRect(.mediaBox) + override func calculate(generator _: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + frame = page.getBoxRect(.mediaBox) return [ (container, self) ] } - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator _: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { if !context.currentPageContainsDrawnContent { // If page is empty and no page is active, we are good to go // Otherwise we need to delete the empty page diff --git a/Source/Internal/Graphics/PDFContext.swift b/Source/Internal/Graphics/PDFContext.swift index e060248a..358a3393 100644 --- a/Source/Internal/Graphics/PDFContext.swift +++ b/Source/Internal/Graphics/PDFContext.swift @@ -1,6 +1,6 @@ // -// File.swift -// +// PDFContext.swift +// // // Created by Philip Niedertscheider on 03.01.21. // @@ -10,7 +10,6 @@ import CoreText /// Encapsulates the graphics context public class PDFContext { - private enum Command { case beginPDFPage(pageConfig: CFDictionary?) case translateBy(x: CGFloat, y: CGFloat) @@ -19,31 +18,31 @@ public class PDFContext { private let cgContext: CGContext - internal private(set) var currentPageContainsDrawnContent = false - internal private(set) var hasActivePage = false + private(set) var currentPageContainsDrawnContent = false + private(set) var hasActivePage = false private var delayedCommands: [Command] = [] - internal init(cgContext: CGContext) { + init(cgContext: CGContext) { self.cgContext = cgContext } // MARK: - PDF - internal func beginPDFPage(_ pageInfo: CFDictionary?) { + func beginPDFPage(_ pageInfo: CFDictionary?) { // Do not create page immediately, instead invoke it as soon as necessary delayedCommands.append(.beginPDFPage(pageConfig: pageInfo)) currentPageContainsDrawnContent = false hasActivePage = true } - internal func endPDFPage() { + func endPDFPage() { applyDelayedCommands() cgContext.endPDFPage() hasActivePage = false } - internal func closePDF() { + func closePDF() { applyDelayedCommands() cgContext.closePDF() hasActivePage = false @@ -51,35 +50,35 @@ public class PDFContext { // MARK: - Coordinate System - internal var userSpaceToDeviceSpaceTransform: CGAffineTransform { + var userSpaceToDeviceSpaceTransform: CGAffineTransform { cgContext.userSpaceToDeviceSpaceTransform } // MARK: - Translation - internal func translateBy(x: CGFloat, y: CGFloat) { + func translateBy(x: CGFloat, y: CGFloat) { delayedCommands.append(.translateBy(x: x, y: y)) } - internal func scaleBy(x: CGFloat, y: CGFloat) { + func scaleBy(x: CGFloat, y: CGFloat) { delayedCommands.append(.scaleBy(x: x, y: y)) } // MARK: - Drawing - internal func drawPath(using mode: CGPathDrawingMode) { + func drawPath(using mode: CGPathDrawingMode) { applyDelayedCommands() cgContext.drawPath(using: mode) currentPageContainsDrawnContent = true } - internal func drawPDFPage(_ page: CGPDFPage) { + func drawPDFPage(_ page: CGPDFPage) { applyDelayedCommands() cgContext.drawPDFPage(page) currentPageContainsDrawnContent = true } - internal func draw(image: CGImage, in frame: CGRect, flipped: Bool) { + func draw(image: CGImage, in frame: CGRect, flipped: Bool) { applyDelayedCommands() cgContext.draw(image: image, in: frame, flipped: flipped) currentPageContainsDrawnContent = true @@ -87,7 +86,7 @@ public class PDFContext { // MARK: - Colors - internal func setFillColor(_ color: CGColor) { + func setFillColor(_ color: CGColor) { applyDelayedCommands() cgContext.setFillColor(color) currentPageContainsDrawnContent = true @@ -95,37 +94,37 @@ public class PDFContext { // MARK: - Paths - internal func beginPath() { + func beginPath() { applyDelayedCommands() cgContext.beginPath() currentPageContainsDrawnContent = true } - internal func addPath(_ path: CGPath) { + func addPath(_ path: CGPath) { applyDelayedCommands() cgContext.addPath(path) currentPageContainsDrawnContent = true } - internal func setLineDash(phase: CGFloat, lengths: [CGFloat]) { + func setLineDash(phase: CGFloat, lengths: [CGFloat]) { applyDelayedCommands() cgContext.setLineDash(phase: phase, lengths: lengths) currentPageContainsDrawnContent = true } - internal func setLineCap(_ cap: CGLineCap) { + func setLineCap(_ cap: CGLineCap) { applyDelayedCommands() cgContext.setLineCap(cap) currentPageContainsDrawnContent = true } - internal func setLineWidth(_ width: CGFloat) { + func setLineWidth(_ width: CGFloat) { applyDelayedCommands() cgContext.setLineWidth(width) currentPageContainsDrawnContent = true } - internal func setStrokeColor(_ color: CGColor) { + func setStrokeColor(_ color: CGColor) { applyDelayedCommands() cgContext.setStrokeColor(color) currentPageContainsDrawnContent = true @@ -133,19 +132,19 @@ public class PDFContext { // MARK: - State - internal func saveGState() { + func saveGState() { applyDelayedCommands() cgContext.saveGState() } - internal func restoreGState() { + func restoreGState() { applyDelayedCommands() cgContext.restoreGState() } // MARK: - CoreText - internal var textMatrix: CGAffineTransform { + var textMatrix: CGAffineTransform { get { cgContext.textMatrix } @@ -154,7 +153,7 @@ public class PDFContext { } } - internal func draw(ctFrame frameRef: CTFrame) { + func draw(ctFrame frameRef: CTFrame) { applyDelayedCommands() CTFrameDraw(frameRef, cgContext) currentPageContainsDrawnContent = true @@ -162,7 +161,7 @@ public class PDFContext { // MARK: - Masking - internal func clip() { + func clip() { applyDelayedCommands() cgContext.clip() currentPageContainsDrawnContent = true @@ -170,7 +169,7 @@ public class PDFContext { // MARK: - Metadata - internal func setURL(_ url: CFURL, for rect: CGRect) { + func setURL(_ url: CFURL, for rect: CGRect) { applyDelayedCommands() cgContext.setURL(url, for: rect) currentPageContainsDrawnContent = true @@ -178,14 +177,14 @@ public class PDFContext { // MARK: - Helpers - internal func resetDelayedCommands() { + func resetDelayedCommands() { delayedCommands = [] } private func applyDelayedCommands() { for command in delayedCommands { switch command { - case .beginPDFPage(let pageConfig): + case let .beginPDFPage(pageConfig): cgContext.beginPDFPage(pageConfig) case let .scaleBy(x, y): cgContext.scaleBy(x: x, y: y) diff --git a/Source/Internal/Graphics/PDFContextGraphics.swift b/Source/Internal/Graphics/PDFContextGraphics.swift index 3b4ef2fb..2182674a 100644 --- a/Source/Internal/Graphics/PDFContextGraphics.swift +++ b/Source/Internal/Graphics/PDFContextGraphics.swift @@ -3,41 +3,41 @@ // TPPDF // // Created by Philip Niedertscheider on 24.06.20. -// Copyright © 2020 Philip Niedertscheider. All rights reserved. // -import Foundation import CoreGraphics +import Foundation -internal enum PDFContextGraphics { - - internal static func createBitmapContext(size: CGSize) -> CGContext? { +enum PDFContextGraphics { + static func createBitmapContext(size: CGSize) -> CGContext? { let colorSpace = CGColorSpaceCreateDeviceRGB() let bytesPerPixel = 4 let bytesPerRow = bytesPerPixel * Int(size.width) let rawData = malloc(Int(size.height) * bytesPerRow) let bitsPerComponent = 8 - return CGContext(data: rawData, - width: Int(size.width), - height: Int(size.height), - bitsPerComponent: bitsPerComponent, - bytesPerRow: bytesPerRow, - space: colorSpace, - bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) + return CGContext( + data: rawData, + width: Int(size.width), + height: Int(size.height), + bitsPerComponent: bitsPerComponent, + bytesPerRow: bytesPerRow, + space: colorSpace, + bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue + ) } - internal static func getImage(from context: CGContext, size: CGSize) -> Image? { + static func getImage(from context: CGContext, size: CGSize) -> Image? { guard let cgImage = context.makeImage() else { return nil } #if os(macOS) - return Image(cgImage: cgImage, size: size) + return Image(cgImage: cgImage, size: size) #elseif os(iOS) - return Image(cgImage: cgImage) + return Image(cgImage: cgImage) #endif } - internal static func createPDFContext(url: URL, bounds: CGRect, info: PDFInfo) -> PDFContext { + static func createPDFContext(url: URL, bounds: CGRect, info: PDFInfo) -> PDFContext { var mediaBox = bounds guard let context = CGContext(url as CFURL, mediaBox: &mediaBox, info.generate() as CFDictionary) else { fatalError("Failed to create PDF rendering context for URL") @@ -45,22 +45,22 @@ internal enum PDFContextGraphics { return PDFContext(cgContext: context) } - internal static func createPDFDataContext(bounds: CGRect, info: PDFInfo) -> (NSMutableData, PDFContext) { + static func createPDFDataContext(bounds: CGRect, info: PDFInfo) -> (NSMutableData, PDFContext) { let data = NSMutableData() let contextInfo = info.generate() var mediaBox = bounds guard let consumer = CGDataConsumer(data: data), - let context = CGContext(consumer: consumer, mediaBox: &mediaBox, contextInfo as CFDictionary) else { + let context = CGContext(consumer: consumer, mediaBox: &mediaBox, contextInfo as CFDictionary) else { fatalError("Failed to create PDF rendering context") } return (data, PDFContext(cgContext: context)) } - internal static func closePDFContext(_ context: PDFContext) { + static func closePDFContext(_ context: PDFContext) { context.closePDF() } - internal static func beginPDFPage(in context: PDFContext, for bounds: CGRect, flipped: Bool = true) { + static func beginPDFPage(in context: PDFContext, for bounds: CGRect, flipped: Bool = true) { var mediaBox = bounds let boxData = NSData(bytes: &mediaBox, length: MemoryLayout.size(ofValue: mediaBox)) let pageInfo = [ @@ -74,7 +74,7 @@ internal enum PDFContextGraphics { } } - internal static func endPDFPage(in context: PDFContext) { + static func endPDFPage(in context: PDFContext) { context.endPDFPage() } } diff --git a/Source/Internal/Graphics/PDFGraphics.swift b/Source/Internal/Graphics/PDFGraphics.swift index af298f18..847c8c2e 100644 --- a/Source/Internal/Graphics/PDFGraphics.swift +++ b/Source/Internal/Graphics/PDFGraphics.swift @@ -6,9 +6,9 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -21,8 +21,7 @@ import AppKit - Image resizing and compression */ -internal enum PDFGraphics { - +enum PDFGraphics { // MARK: - INTERNAL STATIC FUNCS // MARK: - Shape: Line @@ -30,11 +29,11 @@ internal enum PDFGraphics { /** Draws a line from the given `start` to the given `end` point into the current graphics context. - - parameter start: Start point of line - - parameter end: End point of line - - parameter style: Style of drawn line + - Parameter start: Start point of line + - Parameter end: End point of line + - Parameter style: Style of drawn line */ - internal static func drawLine(in context: PDFContext, start: CGPoint, end: CGPoint, style: PDFLineStyle) { + static func drawLine(in context: PDFContext, start: CGPoint, end: CGPoint, style: PDFLineStyle) { guard style.type != .none else { return } @@ -53,11 +52,11 @@ internal enum PDFGraphics { /** Draws a rectangle into the given `frame`. - - parameter rect: Frame of rectangle - - parameter outline: Style of border lines - - parameter fill: Inner color + - Parameter rect: Frame of rectangle + - Parameter outline: Style of border lines + - Parameter fill: Inner color */ - internal static func drawRect(in context: PDFContext, rect: CGRect, outline: PDFLineStyle, fill: Color = .clear) { + static func drawRect(in context: PDFContext, rect: CGRect, outline: PDFLineStyle, fill: Color = .clear) { var path = BezierPath(rect: rect) if let radius = outline.radius { path = BezierPath(roundedRect: rect, cornerRadius: radius) @@ -70,11 +69,11 @@ internal enum PDFGraphics { /** Draws a rectangle into the given `frame`. - - parameter rect: Frame of rectangle - - parameter outline: Style of border lines - - parameter fill: Inner color + - Parameter rect: Frame of rectangle + - Parameter outline: Style of border lines + - Parameter fill: Inner color */ - internal static func drawRect(in context: PDFContext, rect: CGRect, outline: PDFLineStyle, pattern: FillPattern) { + static func drawRect(in context: PDFContext, rect: CGRect, outline: PDFLineStyle, pattern: FillPattern) { var path = BezierPath(rect: rect) if let radius = outline.radius { path = BezierPath(roundedRect: rect, cornerRadius: radius) @@ -87,18 +86,24 @@ internal enum PDFGraphics { // MARK: - Shape Utility /** - TODO: Documentation + * Draws the `path` in the `context` using the given `outline` style for the stroke and `fillColor` for filling the shape + * + * - Parameters: + * - path: Instance of ``BezierPath`` to draw + * - context: PDF graphics context + * - outline: Style of the stroke outline + * - fillColor: ``Color`` used to fill the shape */ - internal static func drawPath(path: BezierPath, in context: PDFContext, outline: PDFLineStyle, fillColor: Color) { + static func drawPath(path: BezierPath, in context: PDFContext, outline: PDFLineStyle, fillColor: Color) { prepareForDrawingPath(path: path.cgPath, in: context, strokeStyle: outline) context.setFillColor(fillColor.cgColor) context.drawPath(using: .fillStroke) } /** - TODO: Documentation + * Helper method to prepare the graphics context `context` to draw the given `path` */ - internal static func prepareForDrawingPath(path: CGPath, in context: PDFContext, strokeStyle: PDFLineStyle) { + static func prepareForDrawingPath(path: CGPath, in context: PDFContext, strokeStyle: PDFLineStyle) { context.beginPath() context.addPath(path) @@ -115,12 +120,12 @@ internal enum PDFGraphics { Array is empty if line type is not a dashed or dotted. This also sets the `BezierPath.lineCapStyle`. - - parameter style: Style of line - - parameter path: Reference to the path, which will be manipulated. + - Parameter style: Style of line + - Parameter path: Reference to the path, which will be manipulated. - - returns: Array with dash values + - Returns: Array with dash values */ - internal static func createDashes(style: PDFLineStyle) -> (lengths: [CGFloat], cap: CGLineCap)? { + static func createDashes(style: PDFLineStyle) -> (lengths: [CGFloat], cap: CGLineCap)? { switch style.type { case .dashed: return ([style.width * 3, style.width * 3], .butt) @@ -136,20 +141,20 @@ internal enum PDFGraphics { /** Creates a scaled version of the given `image` by the given `frame` and add optional corner clipping. - - parameter image: Image to resize and compress - - parameter frame: Frame in which the new image will fit - - parameter shouldResize: Flag if image should be resized to frame before drawing - - parameter shouldCompress: Flag if image should be compressed to quality before drawing - - parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality - - parameter roundCorners: Indicates which corners should be rounded, defaults to be empty - - parameter cornerRadii: Radius of corners which are rounded based on `roundCorners`, if `nil` it will create a fully round image + - Parameter image: Image to resize and compress + - Parameter frame: Frame in which the new image will fit + - Parameter shouldResize: Flag if image should be resized to frame before drawing + - Parameter shouldCompress: Flag if image should be compressed to quality before drawing + - Parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality + - Parameter roundCorners: Indicates which corners should be rounded, defaults to be empty + - Parameter cornerRadii: Radius of corners which are rounded based on `roundCorners`, if `nil` it will create a fully round image - - returns: Resized, compressed and rounded copy of `image` + - Returns: Resized, compressed and rounded copy of `image` */ - internal static func resizeAndCompressImage(image: Image, frame: CGRect, - shouldResize: Bool, shouldCompress: Bool, - quality: CGFloat, - roundCorners: RectCorner = [], cornerRadius: CGFloat? = nil) -> Image { + static func resizeAndCompressImage(image: Image, frame: CGRect, + shouldResize: Bool, shouldCompress: Bool, + quality: CGFloat, + roundCorners: RectCorner = [], cornerRadius: CGFloat? = nil) -> Image { var finalImage = image if shouldResize { @@ -168,13 +173,13 @@ internal enum PDFGraphics { /** Draws a scaled version of the given `image` into the given `frame`. - - parameter image: Image to resize - - parameter frame: Frame in which the new image will fit - - parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality, used for size calculations + - Parameter image: Image to resize + - Parameter frame: Frame in which the new image will fit + - Parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality, used for size calculations - - returns: Resized version of `image` + - Returns: Resized version of `image` */ - internal static func resize(image: Image, frame: CGRect, quality: CGFloat) -> Image { + static func resize(image: Image, frame: CGRect, quality: CGFloat) -> Image { let factor: CGFloat = min(3 * quality, 1) let resizeFactor = factor.isZero ? 0.2 : factor @@ -183,20 +188,20 @@ internal enum PDFGraphics { height: floor(frame.height * resizeFactor)) #if os(iOS) - UIGraphicsBeginImageContext(size) - image.draw(in: CGRect(origin: .zero, size: size)) - let finalImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() + UIGraphicsBeginImageContext(size) + image.draw(in: CGRect(origin: .zero, size: size)) + let finalImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() - return finalImage ?? image + return finalImage ?? image #elseif os(macOS) - let finalImage = NSImage(size: size) - finalImage.lockFocus() - let context = NSGraphicsContext.current! - context.imageInterpolation = .high - image.draw(in: CGRect(origin: .zero, size: size)) - finalImage.unlockFocus() - return finalImage + let finalImage = NSImage(size: size) + finalImage.lockFocus() + let context = NSGraphicsContext.current! + context.imageInterpolation = .high + image.draw(in: CGRect(origin: .zero, size: size)) + finalImage.unlockFocus() + return finalImage #endif } @@ -204,22 +209,22 @@ internal enum PDFGraphics { Performs JPEG compression on the given image. If the given image can not be compressed, it will silently return the original image. - - parameter image: Image to compress - - parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality/least compression + - Parameter image: Image to compress + - Parameter quality: Value between 0.0 and 1.0, where 1.0 is maximum quality/least compression - - returns: Compressed image + - Returns: Compressed image */ - internal static func compress(image: Image, quality: CGFloat) -> Image { + static func compress(image: Image, quality: CGFloat) -> Image { #if os(iOS) - guard let data = image.jpegData(compressionQuality: quality) else { - return image - } + guard let data = image.jpegData(compressionQuality: quality) else { + return image + } #elseif os(macOS) - guard let imageData = image.tiffRepresentation, - let bitmapData = NSBitmapImageRep(data: imageData), - let data = bitmapData.representation(using: .jpeg, properties: [:]) else { + guard let imageData = image.tiffRepresentation, + let bitmapData = NSBitmapImageRep(data: imageData), + let data = bitmapData.representation(using: .jpeg, properties: [:]) else { return image - } + } #endif guard let compressed = Image(data: data) else { return image @@ -230,19 +235,19 @@ internal enum PDFGraphics { /** Clips an image to add round corners - - parameter image: Image to edit - - parameter size: Size of final image, used to calculate correct radii limits - - parameter cornerRadius: Optional value used as radius, if null half of the minimum of the size width or height is used, + - Parameter image: Image to edit + - Parameter size: Size of final image, used to calculate correct radii limits + - Parameter cornerRadius: Optional value used as radius, if null half of the minimum of the size width or height is used, resulting in a round image - - returns: Manipulated image + - Returns: Manipulated image */ - internal static func round(image: Image, frameSize: CGSize, corners: RectCorner, cornerRadius: CGFloat?) -> Image { + static func round(image: Image, frameSize: CGSize, corners: RectCorner, cornerRadius: CGFloat?) -> Image { let size = image.size var cornerRadii = CGSize.zero if var radius = cornerRadius { - radius = radius * (frameSize.width > frameSize.height ? size.width / frameSize.width : size.height / frameSize.height) + radius *= (frameSize.width > frameSize.height ? size.width / frameSize.width : size.height / frameSize.height) cornerRadii = CGSize(width: radius, height: radius) } else { let radius = size.width < size.height ? frameSize.width / 2 : frameSize.height / 2 @@ -252,53 +257,45 @@ internal enum PDFGraphics { let clipPath = BezierPath(roundedRect: CGRect(origin: .zero, size: size), byRoundingCorners: corners, cornerRadii: cornerRadii) #if os(iOS) - UIGraphicsBeginImageContext(size) + UIGraphicsBeginImageContext(size) #elseif os(macOS) - let finalImage = NSImage(size: size) - finalImage.lockFocus() + let finalImage = NSImage(size: size) + finalImage.lockFocus() #endif clipPath.addClip() image.draw(in: CGRect(origin: .zero, size: size)) #if os(iOS) - let finalImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - return finalImage ?? image + let finalImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return finalImage ?? image #elseif os(macOS) - finalImage.unlockFocus() - guard let data = finalImage.tiffRepresentation, - let imageRep = NSBitmapImageRep(data: data), - let pngData = imageRep.representation(using: .png, properties: [:]) else { + finalImage.unlockFocus() + guard let data = finalImage.tiffRepresentation, + let imageRep = NSBitmapImageRep(data: data), + let pngData = imageRep.representation(using: .png, properties: [:]) else { return image - } - return NSImage(data: pngData) ?? image + } + return NSImage(data: pngData) ?? image #endif } /** - Constants for filling, mostly used for debugging elements + * Constants for filling, mostly used for debugging elements */ - internal enum FillPattern { - - /** - TODO: Documentation - */ + enum FillPattern { case dotted(foreColor: Color, backColor: Color) - - /** - TODO: Documentation - */ - internal func setFill(in context: PDFContext) { + func setFill(in context: PDFContext) { switch self { - case .dotted(let foreColor, let backColor): + case let .dotted(foreColor, backColor): let size = CGSize(width: 5, height: 5) #if os(iOS) - UIGraphicsBeginImageContext(size) + UIGraphicsBeginImageContext(size) #elseif os(macOS) - let image = NSImage(size: size) - image.lockFocus() + let image = NSImage(size: size) + image.lockFocus() #endif Color.clear.setStroke() @@ -311,10 +308,10 @@ internal enum PDFGraphics { path.fill() #if os(iOS) - let image = UIGraphicsGetImageFromCurrentImageContext()! - UIGraphicsEndImageContext() + let image = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext() #elseif os(macOS) - image.unlockFocus() + image.unlockFocus() #endif context.setFillColor(Color(patternImage: image).cgColor) diff --git a/Source/Internal/Graphics/PDFLineObject.swift b/Source/Internal/Graphics/PDFLineObject.swift index bd77a10a..e2c9c0ac 100644 --- a/Source/Internal/Graphics/PDFLineObject.swift +++ b/Source/Internal/Graphics/PDFLineObject.swift @@ -6,9 +6,9 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -16,29 +16,28 @@ import AppKit Line is drawn from startPoint and endPoint. */ -internal class PDFLineObject: PDFRenderObject { - +class PDFLineObject: PDFRenderObject { /** Defines the style of the line */ - internal var style: PDFLineStyle + var style: PDFLineStyle /** Starting point of line */ - internal var startPoint: CGPoint + var startPoint: CGPoint /** Ending point of line */ - internal var endPoint: CGPoint + var endPoint: CGPoint /** Initializer - - parameter style: Style of line, defaults to `PDFLineStyle` defaults + - Parameter style: Style of line, defaults to `PDFLineStyle` defaults */ - internal init(style: PDFLineStyle = PDFLineStyle(), startPoint: CGPoint = CGPoint.zero, endPoint: CGPoint = CGPoint.zero) { + init(style: PDFLineStyle = PDFLineStyle(), startPoint: CGPoint = CGPoint.zero, endPoint: CGPoint = CGPoint.zero) { self.style = style self.startPoint = startPoint self.endPoint = endPoint @@ -47,20 +46,20 @@ internal class PDFLineObject: PDFRenderObject { /** Calculates the line start and end point - - parameter generator: Generator which uses this object - - parameter container: Container where the line is set + - Parameter generator: Generator which uses this object + - Parameter container: Container where the line is set - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator _: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { let origin = CGPoint(x: min(startPoint.x, endPoint.x), y: min(startPoint.y, endPoint.y)) let size = CGSize(width: max(startPoint.x, endPoint.x) - origin.x, height: max(startPoint.y, endPoint.y) - origin.y) - self.frame = CGRect(origin: origin, size: size) + frame = CGRect(origin: origin, size: size) return [(container, self)] } @@ -68,21 +67,22 @@ internal class PDFLineObject: PDFRenderObject { /** Draws the line in the calculated frame - - parameter generator: Unused - - parameter container: unused + - Parameter generator: Unused + - Parameter container: unused - - throws: None + - Throws: None */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { PDFGraphics.drawLine( in: context, start: startPoint, end: endPoint, - style: style) + style: style + ) if generator.debug && (style.type == .none) { PDFGraphics.drawRect(in: context, - rect: self.frame, + rect: frame, outline: PDFLineStyle(type: .full, color: .red, width: 1.0), fill: .clear) } @@ -92,7 +92,7 @@ internal class PDFLineObject: PDFRenderObject { /** Creates a copy of this `PDFLineObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFLineObject(style: self.style, startPoint: self.startPoint, endPoint: self.endPoint) + override var copy: PDFRenderObject { + PDFLineObject(style: style, startPoint: startPoint, endPoint: endPoint) } } diff --git a/Source/Internal/Graphics/PDFLineSeparatorObject+Equatable.swift b/Source/Internal/Graphics/PDFLineSeparatorObject+Equatable.swift index 618d3bae..2e22fd3d 100644 --- a/Source/Internal/Graphics/PDFLineSeparatorObject+Equatable.swift +++ b/Source/Internal/Graphics/PDFLineSeparatorObject+Equatable.swift @@ -6,15 +6,11 @@ // extension PDFLineSeparatorObject: Equatable { - - /** - TODO: Documentation - */ + /// nodoc public static func == (lhs: PDFLineSeparatorObject, rhs: PDFLineSeparatorObject) -> Bool { guard lhs.style == rhs.style else { return false } return true } - } diff --git a/Source/Internal/Graphics/PDFLineSeparatorObject.swift b/Source/Internal/Graphics/PDFLineSeparatorObject.swift index 5fce9f33..1df57f22 100644 --- a/Source/Internal/Graphics/PDFLineSeparatorObject.swift +++ b/Source/Internal/Graphics/PDFLineSeparatorObject.swift @@ -1,14 +1,14 @@ // -// PDFLineSeparator.swift +// PDFLineSeparatorObject.swift // TPPDF // // Created by Philip Niedertscheider on 12/08/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -16,70 +16,49 @@ import AppKit Separator line is drawn between left and right indentation. */ -internal class PDFLineSeparatorObject: PDFRenderObject { - - /** - Defines the style of the separator line - */ - internal var style: PDFLineStyle +class PDFLineSeparatorObject: PDFRenderObject { + /// Defines the style of the separator line + var style: PDFLineStyle /** Initializer - - parameter style: Style of line, defaults to `PDFLineStyle` defaults + - Parameter style: Style of line, defaults to `PDFLineStyle` defaults */ - internal init(style: PDFLineStyle = PDFLineStyle()) { + init(style: PDFLineStyle = PDFLineStyle()) { self.style = style } - /** - Calculates the line start and end point - - - parameter generator: Generator which uses this object - - parameter container: Container where the line is set - - - throws: None - - - returns: Self - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { let width = PDFCalculations.calculateAvailableFrameWidth(for: generator, in: container) let size = CGSize(width: width, height: style.width) let position = PDFCalculations.calculateElementPosition(for: generator, in: container, with: size) - self.frame = CGRect(origin: position, size: size) + frame = CGRect(origin: position, size: size) return [(container, self)] } - /** - Draws the line in the calculated frame - - - parameter generator: Unused - - parameter container: unused - - - throws: None - */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + /// nodoc + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { PDFGraphics.drawLine( in: context, - start: CGPoint(x: self.frame.minX, y: self.frame.midY), - end: CGPoint(x: self.frame.maxX, y: self.frame.midY), + start: CGPoint(x: frame.minX, y: frame.midY), + end: CGPoint(x: frame.maxX, y: frame.midY), style: style ) if generator.debug && (style.type == .none) { PDFGraphics.drawRect(in: context, - rect: self.frame, + rect: frame, outline: PDFLineStyle(type: .full, color: .red, width: 1.0), fill: .clear) } applyAttributes(in: context) } - /** - TODO: Documentation - */ - override internal var copy: PDFRenderObject { - PDFLineSeparatorObject(style: self.style) + /// nodoc + override var copy: PDFRenderObject { + PDFLineSeparatorObject(style: style) } } diff --git a/Source/Internal/Graphics/PDFRectangleObject.swift b/Source/Internal/Graphics/PDFRectangleObject.swift index e28df1a9..7ebed30d 100644 --- a/Source/Internal/Graphics/PDFRectangleObject.swift +++ b/Source/Internal/Graphics/PDFRectangleObject.swift @@ -6,9 +6,9 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -16,31 +16,30 @@ import AppKit Sqaure line is drawn between left and right indentation. */ -internal class PDFRectangleObject: PDFRenderObject { - +class PDFRectangleObject: PDFRenderObject { /** Defines the style of the outline */ - internal var lineStyle: PDFLineStyle + var lineStyle: PDFLineStyle /** Defines the size of the rectangle */ - internal var size: CGSize + var size: CGSize /** Defines the fill color the rectangle */ - internal var fillColor: Color + var fillColor: Color /** Initializer - - parameter lineStyle: Style of outline, defaults to `PDFLineStyle` defaults - - parameter size: Size of rectangle, defaults to `CGSize.zero` - - parameter fillColor: Fill color, defaults to `Color.clear` + - Parameter lineStyle: Style of outline, defaults to `PDFLineStyle` defaults + - Parameter size: Size of rectangle, defaults to `CGSize.zero` + - Parameter fillColor: Fill color, defaults to `Color.clear` */ - internal init(lineStyle: PDFLineStyle = PDFLineStyle(), size: CGSize = CGSize.zero, fillColor: Color = Color.clear) { + init(lineStyle: PDFLineStyle = PDFLineStyle(), size: CGSize = CGSize.zero, fillColor: Color = Color.clear) { self.lineStyle = lineStyle self.size = size self.fillColor = fillColor @@ -49,17 +48,17 @@ internal class PDFRectangleObject: PDFRenderObject { /** Calculates the line start and end point - - parameter generator: Generator which uses this object - - parameter container: Container where the line is set + - Parameter generator: Generator which uses this object + - Parameter container: Container where the line is set - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { let position = PDFCalculations.calculateElementPosition(for: generator, in: container, with: size) - self.frame = CGRect(origin: position, size: size) + frame = CGRect(origin: position, size: size) return [(container, self)] } @@ -67,20 +66,20 @@ internal class PDFRectangleObject: PDFRenderObject { /** Draws the line in the calculated frame - - parameter generator: Unused - - parameter container: unused + - Parameter generator: Unused + - Parameter container: unused - - throws: None + - Throws: None */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { - PDFGraphics.drawRect(in: context, rect: self.frame, outline: lineStyle, fill: fillColor) + override func draw(generator _: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { + PDFGraphics.drawRect(in: context, rect: frame, outline: lineStyle, fill: fillColor) applyAttributes(in: context) } /** Creates new `PDFRectangleObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFRectangleObject(lineStyle: self.lineStyle, size: self.size, fillColor: self.fillColor) + override var copy: PDFRenderObject { + PDFRectangleObject(lineStyle: lineStyle, size: size, fillColor: fillColor) } } diff --git a/Source/Internal/Graphics/UIColor+CloseToEqual.swift b/Source/Internal/Graphics/UIColor+CloseToEqual.swift index 749c7785..cd51f276 100644 --- a/Source/Internal/Graphics/UIColor+CloseToEqual.swift +++ b/Source/Internal/Graphics/UIColor+CloseToEqual.swift @@ -1,25 +1,24 @@ // -// Color+CloseToEqual.swift +// UIColor+CloseToEqual.swift // TPPDF // // Created by Philip Niedertscheider on 16/11/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif extension Color { - /** Calculates the red, green, blue and alpha values in the range 0...1 and compares the values up to the decimal specified. - - parameter color: The other `Color` - - returns: `true` if difference is less than specified delta + - Parameter color: The other `Color` + - Returns: `true` if difference is less than specified delta */ - internal func isClose(to color: Color, decimals: Int) -> Bool { + func isClose(to color: Color, decimals: Int) -> Bool { var r1: CGFloat = 0 var g1: CGFloat = 0 var b1: CGFloat = 0 @@ -49,11 +48,11 @@ extension Color { /** Checks if the difference between the given values is less than the given delta. - - parameter val1: First value - - parameter val2: Second value - - parameter decimals:Number of decimal digits + - Parameter val1: First value + - Parameter val2: Second value + - Parameter decimals:Number of decimal digits - - returns: `true` if differnec is small enough, othewise `false` + - Returns: `true` if differnec is small enough, othewise `false` */ private func outOfBounds(val1: CGFloat, val2: CGFloat, decimals: Int) -> Bool { let value1 = Decimal(Double(val1)) @@ -70,5 +69,4 @@ extension Color { } return false } - } diff --git a/Source/Internal/Graphics/UIColor+Hex.swift b/Source/Internal/Graphics/UIColor+Hex.swift deleted file mode 100644 index ef811afe..00000000 --- a/Source/Internal/Graphics/UIColor+Hex.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// UIGraphics+Hex.swift -// TPPDF -// -// Created by Philip Niedertscheider on 04/11/2017. -// - -#if os(iOS) -import UIKit -#elseif os(macOS) -import AppKit -#endif - -extension Color { - - /** - TODO: documentation - */ - internal convenience init(hex: String) throws { - var red: CGFloat = 0.0 - var green: CGFloat = 0.0 - var blue: CGFloat = 0.0 - var alpha: CGFloat = 1.0 - - let scanner = Scanner(string: hex) - var hexValue: CUnsignedLongLong = 0 - - if scanner.scanHexInt64(&hexValue) { - let length = hex.count - - switch length { - case 3: - red = CGFloat((hexValue & 0xF00) >> 8) / 15.0 - green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0 - blue = CGFloat(hexValue & 0x00F) / 15.0 - case 4: - red = CGFloat((hexValue & 0xF000) >> 12) / 15.0 - green = CGFloat((hexValue & 0x0F00) >> 8) / 15.0 - blue = CGFloat((hexValue & 0x00F0) >> 4) / 15.0 - alpha = CGFloat(hexValue & 0x000F) / 15.0 - case 6: - red = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0 - green = CGFloat((hexValue & 0x00FF00) >> 8) / 255.0 - blue = CGFloat(hexValue & 0x0000FF) / 255.0 - case 8: - red = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0 - green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0 - blue = CGFloat((hexValue & 0x0000FF00) >> 8) / 255.0 - alpha = CGFloat(hexValue & 0x000000FF) / 255.0 - default: - throw PDFError.invalidHexLength(length: length) - } - } else { - throw PDFError.invalidHex(hex: hex) - } - - self.init(red: red, green: green, blue: blue, alpha: alpha) - } - - /** - TODO: documentation - */ - internal var hex: String { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - - getRed(&red, green: &green, blue: &blue, alpha: &alpha) - - var rgb = 0 - if alpha == 1.0 { - rgb = (Int)(red * 255) << 16 - rgb |= (Int)(green * 255) << 8 - rgb |= (Int)(blue * 255) << 0 - - return String(format: "#%06x", rgb) - } - - rgb = (Int)(red * 255) << 24 - rgb |= (Int)(green * 255) << 16 - rgb |= (Int)(blue * 255) << 8 - rgb |= (Int)(alpha * 255) << 0 - - return String(format: "#%08x", rgb) - } -} diff --git a/Source/Internal/Graphics/UIImage+Pixel.swift b/Source/Internal/Graphics/UIImage+Pixel.swift deleted file mode 100644 index b07fcaac..00000000 --- a/Source/Internal/Graphics/UIImage+Pixel.swift +++ /dev/null @@ -1,134 +0,0 @@ -// -// Image+Pixel.swift -// TPPDF -// -// Created by Philip Niedertscheider on 05/11/2017. -// - -#if os(iOS) -import UIKit -#elseif os(macOS) -import AppKit -#endif - -/** - TODO: documentation - */ -extension Image { - - /** - TODO: documentation - */ - internal var pixelExtractor: PixelExtractor { - #if os(iOS) - return PixelExtractor(img: self.cgImage!) - #elseif os(macOS) - var imageRect = CGRect(origin: .zero, size: self.size) - let image = self.cgImage(forProposedRect: &imageRect, context: nil, hints: nil)! - return PixelExtractor(img: image) - #endif - } - - /** - TODO: documentation - */ - internal func pixelColor(at location: CGPoint) -> Color { - self.pixelExtractor.colorAt(x: Int(location.x), y: Int(location.y)) - } -} - -/** - https://stackoverflow.com/questions/35029672/getting-pixel-color-from-an-image-using-cgpoint - TODO: documentation - */ -internal class PixelExtractor: NSObject { - - /** - TODO: documentation - */ - internal let image: CGImage - - /** - TODO: documentation - */ - internal let context: CGContext? - - /** - TODO: documentation - */ - internal var width: Int { - image.width - } - - /** - TODO: documentation - */ - internal var height: Int { - image.height - } - - /** - TODO: documentation - */ - internal init(img: CGImage) { - image = img - context = PixelExtractor.createBitmapContext(cgImage: img) - } - - /** - TODO: documentation - */ - internal class func createBitmapContext(cgImage: CGImage) -> CGContext { - // Get image width, height - let pixelsWide = cgImage.width - let pixelsHigh = cgImage.height - - let bitmapBytesPerRow = pixelsWide * 4 - let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh) - - // Use the generic RGB color space. - let colorSpace = CGColorSpaceCreateDeviceRGB() - - // Allocate memory for image data. This is the destination in memory - // where any drawing to the bitmap context will be rendered. - let bitmapData = malloc(bitmapByteCount) - let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue) - let size = CGSize(width: pixelsWide, height: pixelsHigh) - #if os(iOS) - UIGraphicsBeginImageContextWithOptions(size, false, 0.0) - #elseif os(macOS) - // TODO: macOS support - #endif - - // create bitmap - let context = CGContext(data: bitmapData, width: pixelsWide, height: pixelsHigh, bitsPerComponent: 8, - bytesPerRow: bitmapBytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) - - // draw the image onto the context - let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh) - context?.draw(cgImage, in: rect) - - return context! - } - - /** - TODO: documentation - */ - internal func colorAt(x: Int, y: Int) -> Color { - assert(0<=x && x [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { let heights = generator.layout.heights guard let columnState = generator.columnState.copy() as? PDFColumnLayoutState else { throw PDFError.copyingFailed @@ -116,8 +79,8 @@ internal class PDFGroupObject: PDFRenderObject { // Check for page breaks let pageBreaks: [(Int, PDFPageBreakObject)] = calcResult.enumerated() - .compactMap({ ($0.offset, $0.element.1 as? PDFPageBreakObject) }) - .compactMap({ $0.1 == nil ? nil : ($0.0, $0.1!) }) + .compactMap { ($0.offset, $0.element.1 as? PDFPageBreakObject) } + .compactMap { $0.1 == nil ? nil : ($0.0, $0.1!) } if pageBreaks.count == 1 && !allowsBreaks { // If one pagebreak, start group on next page. generator.layout.heights = heights @@ -147,9 +110,11 @@ internal class PDFGroupObject: PDFRenderObject { return result } - private func calculateOnNextPage(generator: PDFGenerator, - container: PDFContainer, - pbObj: PDFPageBreakObject) throws -> [PDFLocatedRenderObject] { + private func calculateOnNextPage( + generator: PDFGenerator, + container: PDFContainer, + pbObj: PDFPageBreakObject + ) throws -> [PDFLocatedRenderObject] { frame = CGRect.null var result: [PDFLocatedRenderObject] = [] @@ -163,7 +128,7 @@ internal class PDFGroupObject: PDFRenderObject { result += try object.calculate(generator: generator, container: container.contentContainer) } - self.frame = isFullPage ? calculateBoundsFrame(generator: generator) : calculateFrame(objects: result) + frame = isFullPage ? calculateBoundsFrame(generator: generator) : calculateFrame(objects: result) generator.layout.heights.add(padding.bottom, to: container) return result } @@ -172,9 +137,6 @@ internal class PDFGroupObject: PDFRenderObject { generator.document.layout.bounds.inset(by: generator.layout.margin) } - /** - TODO: Documentation - */ private func calculateFrame(objects: [(container: PDFContainer, object: PDFRenderObject)]) -> CGRect { var resultFrame = CGRect.null for arg in objects { @@ -196,27 +158,56 @@ internal class PDFGroupObject: PDFRenderObject { return resultFrame } - /** - TODO: Documentation - */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + /// nodoc + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { if let color = backgroundColor { - PDFGraphics.drawRect(in: context, rect: self.frame, outline: self.outline, fill: color) + PDFGraphics.drawRect( + in: context, + rect: frame, + outline: outline, + fill: color + ) } if let shape = backgroundShape { - PDFGraphics.drawPath(path: shape.path.bezierPath(in: self.frame), - in: context, - outline: shape.stroke, - fillColor: shape.fillColor) + PDFGraphics.drawPath( + path: shape.path.bezierPath(in: frame), + in: context, + outline: shape.stroke, + fillColor: shape.fillColor + ) + } + if let image = backgroundImage { + let modifiedImage = PDFGraphics.resizeAndCompressImage( + image: image.image, + frame: frame, + shouldResize: image.options.contains(.resize), + shouldCompress: image.options.contains(.compress), + quality: image.quality, + cornerRadius: image.cornerRadius + ) + + let cgImage: CGImage? + #if os(iOS) + cgImage = modifiedImage.cgImage + #elseif os(macOS) + cgImage = modifiedImage.cgImage(forProposedRect: nil, context: nil, hints: nil) + #endif + if let cgImage = cgImage { + context.draw(image: cgImage, in: frame, flipped: true) + } } if generator.debug { - PDFGraphics.drawRect(in: context, - rect: self.frame, - outline: PDFLineStyle(type: .dashed, color: .red, width: 1.0), fill: .clear) - PDFGraphics.drawRect(in: context, - rect: self.frame.inset(by: padding), - outline: PDFLineStyle(type: .full, color: .purple, width: 1.0), fill: .clear) + PDFGraphics.drawRect( + in: context, + rect: frame, + outline: PDFLineStyle(type: .dashed, color: .red, width: 1.0), fill: .clear + ) + PDFGraphics.drawRect( + in: context, + rect: frame.inset(by: padding), + outline: PDFLineStyle(type: .full, color: .purple, width: 1.0), fill: .clear + ) } applyAttributes(in: context) } @@ -224,14 +215,14 @@ internal class PDFGroupObject: PDFRenderObject { /** Creates a new `PDFGroupObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFGroupObject(objects: self.objects.map { ($0, $1.copy) }, - allowsBreaks: self.allowsBreaks, - isFullPage: self.isFullPage, - backgroundColor: self.backgroundColor, - backgroundImage: self.backgroundImage?.copy, - backgroundShape: self.backgroundShape, - outline: self.outline, - padding: self.padding) + override var copy: PDFRenderObject { + PDFGroupObject(objects: objects.map { ($0, $1.copy) }, + allowsBreaks: allowsBreaks, + isFullPage: isFullPage, + backgroundColor: backgroundColor, + backgroundImage: backgroundImage?.copy, + backgroundShape: backgroundShape, + outline: outline, + padding: padding) } } diff --git a/Source/Internal/Image/PDFImageObject.swift b/Source/Internal/Image/PDFImageObject.swift index 988f2b60..0618aa45 100644 --- a/Source/Internal/Image/PDFImageObject.swift +++ b/Source/Internal/Image/PDFImageObject.swift @@ -6,33 +6,32 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Calculates the given image and a caption if necessary */ -internal class PDFImageObject: PDFRenderObject { - +class PDFImageObject: PDFRenderObject { /** Image object holding all information */ - internal var image: PDFImage + var image: PDFImage /** Spacing between image and caption */ - internal var captionSpacing: CGFloat + var captionSpacing: CGFloat /** Initializer - - parameter image: Image object - - parameter captionSpacing: Spacing to caption, defaults to zero + - Parameter image: Image object + - Parameter captionSpacing: Spacing to caption, defaults to zero */ - internal init(image: PDFImage, captionSpacing: CGFloat = 0) { + init(image: PDFImage, captionSpacing: CGFloat = 0) { self.image = image self.captionSpacing = captionSpacing } @@ -40,14 +39,14 @@ internal class PDFImageObject: PDFRenderObject { /** Calculates the frame of the image and additionally returns one or multiple caption objects. - - parameter generator: Current instance handling the calculations - - parameter container: Container where the image is placed in + - Parameter generator: Current instance handling the calculations + - Parameter container: Container where the image is placed in - - throws: Caption calculation errors, see ```PDFAttributedTextObject.calculate(_:,_:)``` + - Throws: Caption calculation errors, see ```PDFAttributedTextObject.calculate(_:,_:)``` - - returns: Calculated objects and their corresponding container, created by this calculation + - Returns: Calculated objects and their corresponding container, created by this calculation */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] var (imageSize, captionSize) = PDFCalculations.calculateImageCaptionSize(generator: generator, @@ -66,17 +65,18 @@ internal class PDFImageObject: PDFRenderObject { container: container, image: image, size: image.size, - sizeFit: image.sizeFit) + sizeFit: image.sizeFit + ) } } let position = PDFCalculations.calculateElementPosition(for: generator, in: container, with: imageSize) - self.frame = CGRect(origin: position, size: imageSize) + frame = CGRect(origin: position, size: imageSize) updateHeights(generator: generator, container: container) result.append((container, self)) for attribute in image.attributes { - self.attributes.append((attribute: attribute, frame: self.frame)) + attributes.append((attribute: attribute, frame: frame)) } if let caption = image.caption { @@ -88,10 +88,10 @@ internal class PDFImageObject: PDFRenderObject { /** Modifies the image and draws it in the previously calculated frame - - parameter generator: Current instance handling the drawing - - parameter container: Container where the image is placed in + - Parameter generator: Current instance handling the drawing + - Parameter container: Container where the image is placed in */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator _: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { var roundedCorners: RectCorner = [] if image.options.contains(.rounded) { roundedCorners = .allCorners @@ -120,9 +120,9 @@ internal class PDFImageObject: PDFRenderObject { let cgImage: CGImage? #if os(iOS) - cgImage = modifiedImage.cgImage + cgImage = modifiedImage.cgImage #elseif os(macOS) - cgImage = modifiedImage.cgImage(forProposedRect: nil, context: nil, hints: nil) + cgImage = modifiedImage.cgImage(forProposedRect: nil, context: nil, hints: nil) #endif if let cgImage = cgImage { context.draw(image: cgImage, in: frame, flipped: true) @@ -134,17 +134,17 @@ internal class PDFImageObject: PDFRenderObject { /** Adds the image and caption height to the content height - - parameter generator: Current instance handling the calculations - - parameter container: Container where the image is placed in + - Parameter generator: Current instance handling the calculations + - Parameter container: Container where the image is placed in */ - internal func updateHeights(generator: PDFGenerator, container: PDFContainer) { - generator.layout.heights.add(frame.height + (self.image.caption != nil ? captionSpacing : 0), to: container) + func updateHeights(generator: PDFGenerator, container: PDFContainer) { + generator.layout.heights.add(frame.height + (image.caption != nil ? captionSpacing : 0), to: container) } /** Creates a new `PDFImageObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFImageObject(image: self.image.copy, captionSpacing: self.captionSpacing) + override var copy: PDFRenderObject { + PDFImageObject(image: image.copy, captionSpacing: captionSpacing) } } diff --git a/Source/Internal/Image/PDFImageRowObject.swift b/Source/Internal/Image/PDFImageRowObject.swift index bfabb4f0..3481bc77 100644 --- a/Source/Internal/Image/PDFImageRowObject.swift +++ b/Source/Internal/Image/PDFImageRowObject.swift @@ -6,44 +6,24 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: documentation - */ -internal class PDFImageRowObject: PDFRenderObject { - - /** - TODO: documentation - */ - internal var images: [PDFImage] - - /** - TODO: documentation - */ - internal var spacing: CGFloat - - /** - TODO: documentation - */ - internal var captionSpacing: CGFloat - - /** - TODO: documentation - */ - internal init(images: [PDFImage], spacing: CGFloat = 1.0, captionSpacing: CGFloat = 5.0) { +class PDFImageRowObject: PDFRenderObject { + var images: [PDFImage] + var spacing: CGFloat + var captionSpacing: CGFloat + + init(images: [PDFImage], spacing: CGFloat = 1.0, captionSpacing: CGFloat = 5.0) { self.images = images self.spacing = spacing self.captionSpacing = captionSpacing } - /** - TODO: documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] let originalInsetLeft = generator.layout.indentation.leftIn(container: container) @@ -66,10 +46,14 @@ internal class PDFImageRowObject: PDFRenderObject { let imageObject = PDFImageObject(image: image, captionSpacing: captionSpacing) - generator.layout.indentation.setLeft(indentation: originalInsetLeft + additionInset + spacing * CGFloat(idx), - in: container) - generator.layout.indentation.setRight(indentation: originalInsetRight + (imageWidth + spacing) * CGFloat(images.count - idx - 1), - in: container) + generator.layout.indentation.setLeft( + indentation: originalInsetLeft + additionInset + spacing * CGFloat(idx), + in: container + ) + generator.layout.indentation.setRight( + indentation: originalInsetRight + (imageWidth + spacing) * CGFloat(images.count - idx - 1), + in: container + ) let res = try imageObject.calculate(generator: generator, container: container) if res.contains(where: { $0.1 is PDFPageBreakObject }) { @@ -91,10 +75,8 @@ internal class PDFImageRowObject: PDFRenderObject { return result } - /** - TODO: documentation - */ - override internal var copy: PDFRenderObject { - PDFImageRowObject(images: self.images, spacing: self.spacing, captionSpacing: self.captionSpacing) + /// nodoc + override var copy: PDFRenderObject { + PDFImageRowObject(images: images, spacing: spacing, captionSpacing: captionSpacing) } } diff --git a/Source/Internal/Layout/PDFColumnLayoutState.swift b/Source/Internal/Layout/PDFColumnLayoutState.swift index f22c8ecf..fc91b57f 100644 --- a/Source/Internal/Layout/PDFColumnLayoutState.swift +++ b/Source/Internal/Layout/PDFColumnLayoutState.swift @@ -6,82 +6,49 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ -internal class PDFColumnLayoutState: CustomStringConvertible { - - /** - TODO: Documentation - */ +class PDFColumnLayoutState: CustomStringConvertible { private var maxColumns: [PDFContainer: Int] - - /** - TODO: Documentation - */ private var currentColumn: [PDFContainer: Int] - - /** - TODO: Documentation - */ private var columnWidths: [PDFContainer: [CGFloat]] - - /** - TODO: Documentation - */ private var columnSpacings: [PDFContainer: [CGFloat]] - - /** - TODO: Documentation - */ private var wrapColumnsHeight: [PDFContainer: CGFloat] - - /** - TODO: Documentation - */ private var inset: [PDFContainer: (left: CGFloat, right: CGFloat)] - /** - TODO: Documentation - */ - internal init() { - maxColumns = [:] - currentColumn = [ + init() { + self.maxColumns = [:] + self.currentColumn = [ .headerLeft: 0, .contentLeft: 0, .footerLeft: 0 ] - columnWidths = [ + self.columnWidths = [ .headerLeft: [], .contentLeft: [], .footerLeft: [] ] - columnSpacings = [ + self.columnSpacings = [ .headerLeft: [], .contentLeft: [], .footerLeft: [] ] - wrapColumnsHeight = [ + self.wrapColumnsHeight = [ .headerLeft: 0, .contentLeft: 0, .footerLeft: 0 ] - inset = [ + self.inset = [ .headerLeft: (0, 0), .contentLeft: (0, 0), .footerLeft: (0, 0) ] } - /** - TODO: Documentation - */ - internal func reset() { + func reset() { maxColumns = [:] currentColumn = [ .headerLeft: 0, @@ -110,10 +77,7 @@ internal class PDFColumnLayoutState: CustomStringConvertible { ] } - /** - TODO: Documentation - */ - internal func set(maxColumns: Int?, for container: PDFContainer) { + func set(maxColumns: Int?, for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.maxColumns[.headerLeft] = maxColumns @@ -126,23 +90,20 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getMaxColumns(for container: PDFContainer) -> Int? { + func getMaxColumns(for container: PDFContainer) -> Int? { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.maxColumns[.headerLeft] + return maxColumns[.headerLeft] case .contentLeft, .contentCenter, .contentRight: - return self.maxColumns[.contentLeft] + return maxColumns[.contentLeft] case .footerLeft, .footerCenter, .footerRight: - return self.maxColumns[.footerRight] + return maxColumns[.footerRight] default: return nil } } - /** - TODO: Documentation - */ - internal func set(wrapColumnsHeight: CGFloat, for container: PDFContainer) { + func set(wrapColumnsHeight: CGFloat, for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.wrapColumnsHeight[.headerLeft] = wrapColumnsHeight @@ -155,23 +116,20 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getWrapColumnsHeight(for container: PDFContainer) -> CGFloat { + func getWrapColumnsHeight(for container: PDFContainer) -> CGFloat { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.wrapColumnsHeight[.headerLeft] ?? 0 + return wrapColumnsHeight[.headerLeft] ?? 0 case .contentLeft, .contentCenter, .contentRight: - return self.wrapColumnsHeight[.contentLeft] ?? 0 + return wrapColumnsHeight[.contentLeft] ?? 0 case .footerLeft, .footerCenter, .footerRight: - return self.wrapColumnsHeight[.footerRight] ?? 0 + return wrapColumnsHeight[.footerRight] ?? 0 default: return 0 } } - /** - TODO: Documentation - */ - internal func set(currentColumn: Int, for container: PDFContainer) { + func set(currentColumn: Int, for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.currentColumn[.headerLeft] = currentColumn @@ -184,23 +142,20 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getCurrentColumn(for container: PDFContainer) -> Int { + func getCurrentColumn(for container: PDFContainer) -> Int { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.currentColumn[.headerLeft] ?? 0 + return currentColumn[.headerLeft] ?? 0 case .contentLeft, .contentCenter, .contentRight: - return self.currentColumn[.contentLeft] ?? 0 + return currentColumn[.contentLeft] ?? 0 case .footerLeft, .footerCenter, .footerRight: - return self.currentColumn[.footerRight] ?? 0 + return currentColumn[.footerRight] ?? 0 default: return 0 } } - /** - TODO: Documentation - */ - internal func set(columnSpacings: [CGFloat], for container: PDFContainer) { + func set(columnSpacings: [CGFloat], for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.columnSpacings[.headerLeft] = columnSpacings @@ -213,23 +168,20 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getColumnSpacings(for container: PDFContainer) -> [CGFloat] { + func getColumnSpacings(for container: PDFContainer) -> [CGFloat] { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.columnSpacings[.headerLeft] ?? [] + return columnSpacings[.headerLeft] ?? [] case .contentLeft, .contentCenter, .contentRight: - return self.columnSpacings[.contentLeft] ?? [] + return columnSpacings[.contentLeft] ?? [] case .footerLeft, .footerCenter, .footerRight: - return self.columnSpacings[.footerRight] ?? [] + return columnSpacings[.footerRight] ?? [] default: return [] } } - /** - TODO: Documentation - */ - internal func set(inset: (left: CGFloat, right: CGFloat), for container: PDFContainer) { + func set(inset: (left: CGFloat, right: CGFloat), for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.inset[.headerLeft] = inset @@ -242,23 +194,20 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getInset(for container: PDFContainer) -> (left: CGFloat, right: CGFloat) { + func getInset(for container: PDFContainer) -> (left: CGFloat, right: CGFloat) { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.inset[.headerLeft] ?? (0, 0) + return inset[.headerLeft] ?? (0, 0) case .contentLeft, .contentCenter, .contentRight: - return self.inset[.contentLeft] ?? (0, 0) + return inset[.contentLeft] ?? (0, 0) case .footerLeft, .footerCenter, .footerRight: - return self.inset[.footerRight] ?? (0, 0) + return inset[.footerRight] ?? (0, 0) default: return (0, 0) } } - /** - TODO: Documentation - */ - internal func set(columnWidths: [CGFloat], for container: PDFContainer) { + func set(columnWidths: [CGFloat], for container: PDFContainer) { switch container { case .headerLeft, .headerCenter, .headerRight: self.columnWidths[.headerLeft] = columnWidths @@ -271,36 +220,33 @@ internal class PDFColumnLayoutState: CustomStringConvertible { } } - internal func getColumnWidths(for container: PDFContainer) -> [CGFloat] { + func getColumnWidths(for container: PDFContainer) -> [CGFloat] { switch container { case .headerLeft, .headerCenter, .headerRight: - return self.columnWidths[.headerLeft] ?? [] + return columnWidths[.headerLeft] ?? [] case .contentLeft, .contentCenter, .contentRight: - return self.columnWidths[.contentLeft] ?? [] + return columnWidths[.contentLeft] ?? [] case .footerLeft, .footerCenter, .footerRight: - return self.columnWidths[.footerRight] ?? [] + return columnWidths[.footerRight] ?? [] default: return [] } } } -/** - TODO: Documentation - */ -extension PDFColumnLayoutState: NSCopying { +// MARK: NSCopying - /** - TODO: Documentation - */ - internal func copy(with zone: NSZone? = nil) -> Any { +/// nodoc +extension PDFColumnLayoutState: NSCopying { + /// nodoc + func copy(with _: NSZone? = nil) -> Any { let state = PDFColumnLayoutState() - state.maxColumns = self.maxColumns - state.currentColumn = self.currentColumn - state.columnWidths = self.columnWidths - state.columnSpacings = self.columnSpacings - state.wrapColumnsHeight = self.wrapColumnsHeight - state.inset = self.inset + state.maxColumns = maxColumns + state.currentColumn = currentColumn + state.columnWidths = columnWidths + state.columnSpacings = columnSpacings + state.wrapColumnsHeight = wrapColumnsHeight + state.inset = inset return state } } diff --git a/Source/Internal/Layout/PDFIndentationObject+Equatable.swift b/Source/Internal/Layout/PDFIndentationObject+Equatable.swift index 47a66d4b..200b2f07 100644 --- a/Source/Internal/Layout/PDFIndentationObject+Equatable.swift +++ b/Source/Internal/Layout/PDFIndentationObject+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 14/11/2017. // -/** - TODO: documentation - */ extension PDFIndentationObject: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFIndentationObject, rhs: PDFIndentationObject) -> Bool { guard lhs.indentation == rhs.indentation else { return false diff --git a/Source/Internal/Layout/PDFIndentationObject.swift b/Source/Internal/Layout/PDFIndentationObject.swift index 851feb67..eea674ee 100644 --- a/Source/Internal/Layout/PDFIndentationObject.swift +++ b/Source/Internal/Layout/PDFIndentationObject.swift @@ -6,39 +6,38 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Used to modify the indentation of a container */ -internal class PDFIndentationObject: PDFRenderObject { - +class PDFIndentationObject: PDFRenderObject { /** Offset from edge of container */ - internal var indentation: CGFloat + var indentation: CGFloat /** Offset is from left edge if `true`, right if `false` */ - internal var left: Bool + var left: Bool /** Flag to check if section inset inside column needs to be changed. If `true`, the indention is relative to the column left guide */ - internal var insideSectionColumn: Bool + var insideSectionColumn: Bool /** Initializer - - parameter indentation: Offset in points from edge - - parameter left: Offset is from left side if `true`, from right if `false` + - Parameter indentation: Offset in points from edge + - Parameter left: Offset is from left side if `true`, from right if `false` */ - internal init(indentation: CGFloat, left: Bool, insideSectionColumn: Bool) { + init(indentation: CGFloat, left: Bool, insideSectionColumn: Bool) { self.indentation = indentation self.left = left self.insideSectionColumn = insideSectionColumn @@ -47,14 +46,14 @@ internal class PDFIndentationObject: PDFRenderObject { /** Modifies the indentation of the given `generator` in the given `container` - - parameter generator: Generator which uses this object - - parameter container: Container where the indentation will change + - Parameter generator: Generator which uses this object + - Parameter container: Container where the indentation will change - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var indent = indentation if left { if insideSectionColumn { @@ -74,7 +73,7 @@ internal class PDFIndentationObject: PDFRenderObject { /** Creates a new `PDFIndentationObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFIndentationObject(indentation: self.indentation, left: self.left, insideSectionColumn: self.insideSectionColumn) + override var copy: PDFRenderObject { + PDFIndentationObject(indentation: indentation, left: left, insideSectionColumn: insideSectionColumn) } } diff --git a/Source/Internal/Layout/PDFLayout+Equatable.swift b/Source/Internal/Layout/PDFLayout+Equatable.swift index f718227b..586541a6 100644 --- a/Source/Internal/Layout/PDFLayout+Equatable.swift +++ b/Source/Internal/Layout/PDFLayout+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 09/11/2017. // -/** - TODO: documentation - */ extension PDFLayout: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFLayout, rhs: PDFLayout) -> Bool { guard lhs.heights == rhs.heights else { return false diff --git a/Source/Internal/Layout/PDFLayout.swift b/Source/Internal/Layout/PDFLayout.swift index f115f9d4..dbb9dc20 100644 --- a/Source/Internal/Layout/PDFLayout.swift +++ b/Source/Internal/Layout/PDFLayout.swift @@ -6,37 +6,20 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Contains all relevant layout informations of a pdf document */ -internal class PDFLayout: CustomStringConvertible { +class PDFLayout: CustomStringConvertible { + var heights = PDFLayoutHeights() + var indentation = PDFLayoutIndentations() + var margin: EdgeInsets = .zero - /** - TODO: documentation - */ - internal var heights = PDFLayoutHeights() - - /** - TODO: documentation - */ - internal var indentation = PDFLayoutIndentations() - - /** - TODO: documentation - */ - internal var margin: EdgeInsets = .zero - - // MARK: - INTERNAL FUNCS - - /** - TODO: documentation - */ - internal func getContentOffset(in container: PDFContainer) -> CGFloat { + func getContentOffset(in container: PDFContainer) -> CGFloat { if container.isHeader { return heights.header[container]! } else if container.isFooter { @@ -45,10 +28,7 @@ internal class PDFLayout: CustomStringConvertible { return heights.content } - /** - TODO: documentation - */ - internal func setContentOffset(in container: PDFContainer, to value: CGFloat) { + func setContentOffset(in container: PDFContainer, to value: CGFloat) { if container.isHeader { heights.header[container] = value } else if container.isFooter { @@ -58,10 +38,7 @@ internal class PDFLayout: CustomStringConvertible { } } - /** - TODO: documentation - */ - internal func reset() { + func reset() { heights = PDFLayoutHeights() indentation = PDFLayoutIndentations() margin = .zero diff --git a/Source/Internal/Layout/PDFLayoutHeights+Equatable.swift b/Source/Internal/Layout/PDFLayoutHeights+Equatable.swift index 0c97fa15..5b4d31dc 100644 --- a/Source/Internal/Layout/PDFLayoutHeights+Equatable.swift +++ b/Source/Internal/Layout/PDFLayoutHeights+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 12/11/2017. // -/** - TODO: documentation - */ extension PDFLayoutHeights: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFLayoutHeights, rhs: PDFLayoutHeights) -> Bool { guard lhs.header == rhs.header else { return false diff --git a/Source/Internal/Layout/PDFLayoutHeights.swift b/Source/Internal/Layout/PDFLayoutHeights.swift index 747549c9..adea90ef 100644 --- a/Source/Internal/Layout/PDFLayoutHeights.swift +++ b/Source/Internal/Layout/PDFLayoutHeights.swift @@ -6,42 +6,22 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: documentation - */ -internal struct PDFLayoutHeights: CustomStringConvertible { +struct PDFLayoutHeights: CustomStringConvertible { + var header: [PDFContainer: CGFloat] = [:] + var footer: [PDFContainer: CGFloat] = [:] + var content: CGFloat = 0 - /** - TODO: documentation - */ - internal var header: [PDFContainer: CGFloat] = [:] - - /** - TODO: documentation - */ - internal var footer: [PDFContainer: CGFloat] = [:] - - /** - Tracks the current height of the document content - */ - internal var content: CGFloat = 0 - - /** - Initializes the heights by resetting the headers and footers - */ - internal init() { + init() { resetHeaderFooterHeight() } - /** - Resets all three header and footer containers to be zero - */ - internal mutating func resetHeaderFooterHeight() { + /// Resets all three header and footer containers to be zero + mutating func resetHeaderFooterHeight() { header[.headerLeft] = 0 header[.headerCenter] = 0 header[.headerRight] = 0 @@ -51,10 +31,7 @@ internal struct PDFLayoutHeights: CustomStringConvertible { footer[.footerRight] = 0 } - /** - TODO: documentation - */ - internal mutating func add(_ value: CGFloat, to container: PDFContainer) { + mutating func add(_ value: CGFloat, to container: PDFContainer) { if container.isHeader { header[container] = (header[container] ?? 0) + value } else if container.isFooter { @@ -65,23 +42,20 @@ internal struct PDFLayoutHeights: CustomStringConvertible { } /** - - returns: Height of highest header container + * - Returns: Height of highest header container */ - internal func maxHeaderHeight() -> CGFloat { + func maxHeaderHeight() -> CGFloat { header.values.max() ?? 0 } /** - - returns: Height of highestfooter container + * - Returns: Height of highest footer container */ - internal func maxFooterHeight() -> CGFloat { + func maxFooterHeight() -> CGFloat { footer.values.max() ?? 0 } - /** - TODO: documentation - */ - internal func value(for container: PDFContainer) -> CGFloat { + func value(for container: PDFContainer) -> CGFloat { if container.isHeader { return header[container] ?? 0 } else if container.isFooter { @@ -91,10 +65,7 @@ internal struct PDFLayoutHeights: CustomStringConvertible { } } - /** - TODO: documentation - */ - internal mutating func set(_ value: CGFloat, to container: PDFContainer) { + mutating func set(_ value: CGFloat, to container: PDFContainer) { if container.isHeader { header[container] = value } else if container.isFooter { diff --git a/Source/Internal/Layout/PDFLayoutIndentations+Equatable.swift b/Source/Internal/Layout/PDFLayoutIndentations+Equatable.swift index 334b552c..116c4c1e 100644 --- a/Source/Internal/Layout/PDFLayoutIndentations+Equatable.swift +++ b/Source/Internal/Layout/PDFLayoutIndentations+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 12/11/2017. // -/** - TODO: documentation - */ extension PDFLayoutIndentations: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFLayoutIndentations, rhs: PDFLayoutIndentations) -> Bool { guard lhs.header == rhs.header else { return false diff --git a/Source/Internal/Layout/PDFLayoutIndentations.swift b/Source/Internal/Layout/PDFLayoutIndentations.swift index e4e01bd1..89f47873 100644 --- a/Source/Internal/Layout/PDFLayoutIndentations.swift +++ b/Source/Internal/Layout/PDFLayoutIndentations.swift @@ -6,41 +6,40 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Holds indentations of header, content and footer. */ -internal struct PDFLayoutIndentations: CustomStringConvertible { - +struct PDFLayoutIndentations: CustomStringConvertible { /** Left and right indentation of header containers */ - internal var header: (left: CGFloat, right: CGFloat) = (0, 0) + var header: (left: CGFloat, right: CGFloat) = (0, 0) /** Left and right indentation of content containers */ - internal var content: (left: CGFloat, right: CGFloat) = (0, 0) + var content: (left: CGFloat, right: CGFloat) = (0, 0) /** Left and right indentation of footer containers */ - internal var footer: (left: CGFloat, right: CGFloat) = (0, 0) + var footer: (left: CGFloat, right: CGFloat) = (0, 0) // MARK: - INTERNAL FUNCS /** The given container is normalized and then returns the left indentation from either header, content or footer. - - parameter container: Container whose left indentation is requested + - Parameter container: Container whose left indentation is requested - - returns: Left indentation of given container + - Returns: Left indentation of given container */ - internal func leftIn(container: PDFContainer) -> CGFloat { + func leftIn(container: PDFContainer) -> CGFloat { if container.isHeader { return header.left } else if container.isFooter { @@ -52,11 +51,11 @@ internal struct PDFLayoutIndentations: CustomStringConvertible { /** The given container is normalized and then returns the right indentation from either header, content or footer. - - parameter container: Container whose right indentation is requested + - Parameter container: Container whose right indentation is requested - - returns: Right indentation of given container + - Returns: Right indentation of given container */ - internal func rightIn(container: PDFContainer) -> CGFloat { + func rightIn(container: PDFContainer) -> CGFloat { if container.isHeader { return header.right } else if container.isFooter { @@ -68,10 +67,10 @@ internal struct PDFLayoutIndentations: CustomStringConvertible { /** Sets the given `indentation` as the left indentation in the normalized container `container`. - - parameter indentation: Distance of points - - parameter container: Corresponding container + - Parameter indentation: Distance of points + - Parameter container: Corresponding container */ - internal mutating func setLeft(indentation: CGFloat, in container: PDFContainer) { + mutating func setLeft(indentation: CGFloat, in container: PDFContainer) { if container.isHeader { header.left = indentation } else if container.isFooter { @@ -84,10 +83,10 @@ internal struct PDFLayoutIndentations: CustomStringConvertible { /** Sets the given `indentation` as the right indentation in the normalized container `container`. - - parameter indentation: Distance of points - - parameter container: Corresponding container + - Parameter indentation: Distance of points + - Parameter container: Corresponding container */ - internal mutating func setRight(indentation: CGFloat, in container: PDFContainer) { + mutating func setRight(indentation: CGFloat, in container: PDFContainer) { if container.isHeader { header.right = indentation } else if container.isFooter { diff --git a/Source/Internal/Layout/PDFMarginObject.swift b/Source/Internal/Layout/PDFMarginObject.swift index e31a4e1c..fb45b0d9 100644 --- a/Source/Internal/Layout/PDFMarginObject.swift +++ b/Source/Internal/Layout/PDFMarginObject.swift @@ -6,52 +6,30 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ -internal class PDFMarginObject: PDFRenderObject { +class PDFMarginObject: PDFRenderObject { + var values: (left: CGFloat?, right: CGFloat?, top: CGFloat?, bottom: CGFloat?) + var reset: Bool - /** - TODO: Documentation - */ - internal var values: (left: CGFloat?, right: CGFloat?, top: CGFloat?, bottom: CGFloat?) - - /** - TODO: Documentation - */ - internal var reset: Bool - - /** - TODO: Documentation - */ - internal convenience init(reset: Bool) { + convenience init(reset: Bool) { self.init(left: nil, right: nil, top: nil, bottom: nil, reset: reset) } - /** - TODO: Documentation - */ - internal convenience init(left: CGFloat? = nil, right: CGFloat? = nil, top: CGFloat? = nil, bottom: CGFloat? = nil) { + convenience init(left: CGFloat? = nil, right: CGFloat? = nil, top: CGFloat? = nil, bottom: CGFloat? = nil) { self.init(left: left, right: right, top: top, bottom: bottom, reset: false) } - /** - TODO: Documentation - */ - internal init(left: CGFloat?, right: CGFloat?, top: CGFloat?, bottom: CGFloat?, reset: Bool) { + init(left: CGFloat?, right: CGFloat?, top: CGFloat?, bottom: CGFloat?, reset: Bool) { self.values = (left, right, top, bottom) self.reset = reset } - /** - TODO: Documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { if reset { generator.layout.margin = generator.document.layout.margin return [(container, self)] @@ -72,14 +50,14 @@ internal class PDFMarginObject: PDFRenderObject { return [(container, self)] } - /** - TODO: Documentation - */ - override internal var copy: PDFRenderObject { - PDFMarginObject(left: self.values.left, - right: self.values.right, - top: self.values.top, - bottom: self.values.bottom, - reset: self.reset) + /// nodoc + override var copy: PDFRenderObject { + PDFMarginObject( + left: values.left, + right: values.right, + top: values.top, + bottom: values.bottom, + reset: reset + ) } } diff --git a/Source/Internal/Layout/PDFOffsetObject+Equatable.swift b/Source/Internal/Layout/PDFOffsetObject+Equatable.swift index 328108b0..47834754 100644 --- a/Source/Internal/Layout/PDFOffsetObject+Equatable.swift +++ b/Source/Internal/Layout/PDFOffsetObject+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 14/11/2017. // -/** - TODO: documentation - */ extension PDFOffsetObject: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFOffsetObject, rhs: PDFOffsetObject) -> Bool { guard lhs.offset == rhs.offset else { return false diff --git a/Source/Internal/Layout/PDFOffsetObject.swift b/Source/Internal/Layout/PDFOffsetObject.swift index 41ce5808..5673985e 100644 --- a/Source/Internal/Layout/PDFOffsetObject.swift +++ b/Source/Internal/Layout/PDFOffsetObject.swift @@ -6,40 +6,39 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Used to modify the offset of a container */ -internal class PDFOffsetObject: PDFRenderObject { - +class PDFOffsetObject: PDFRenderObject { /** Offset from top edge of container */ - internal var offset: CGFloat + var offset: CGFloat /** Initializer with point offset - - parameter offset: Points from the top edge of the container + - Parameter offset: Points from the top edge of the container */ - internal init(offset: CGFloat) { + init(offset: CGFloat) { self.offset = offset } /** Modifies the layout of the given `generator`. - - parameter generator: Generator which uses this object - - parameter container: Container where this object is located + - Parameter generator: Generator which uses this object + - Parameter container: Container where this object is located - - returns: Self + - Returns: Self */ @discardableResult - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { generator.layout.setContentOffset(in: container, to: offset) return [(container, self)] @@ -48,7 +47,7 @@ internal class PDFOffsetObject: PDFRenderObject { /** Creates a news `PDFOffsetObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFOffsetObject(offset: self.offset) + override var copy: PDFRenderObject { + PDFOffsetObject(offset: offset) } } diff --git a/Source/Internal/Layout/PDFPageBreakObject+Equatable.swift b/Source/Internal/Layout/PDFPageBreakObject+Equatable.swift index 98c022b1..3709324c 100644 --- a/Source/Internal/Layout/PDFPageBreakObject+Equatable.swift +++ b/Source/Internal/Layout/PDFPageBreakObject+Equatable.swift @@ -5,15 +5,9 @@ // Created by Philip Niedertscheider on 14/11/2017. // -/** - TODO: documentation - */ extension PDFPageBreakObject: Equatable { - - /** - TODO: documentation - */ - public static func == (lhs: PDFPageBreakObject, rhs: PDFPageBreakObject) -> Bool { + /// nodoc + public static func == (_: PDFPageBreakObject, _: PDFPageBreakObject) -> Bool { true } } diff --git a/Source/Internal/Layout/PDFPageBreakObject.swift b/Source/Internal/Layout/PDFPageBreakObject.swift index 1d4281f9..1ecd24f1 100644 --- a/Source/Internal/Layout/PDFPageBreakObject.swift +++ b/Source/Internal/Layout/PDFPageBreakObject.swift @@ -6,34 +6,28 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import CoreGraphics -/** - Used in the rendering to create a new page - */ -internal class PDFPageBreakObject: PDFRenderObject { - - /** - TODO: Documentation - */ - internal var stayOnSamePage: Bool = false +/// Used in the rendering to create a new page +class PDFPageBreakObject: PDFRenderObject { + var stayOnSamePage: Bool = false /** Modifies the layout and page count of the given `generator`. The parameter `container` is unused, as page breaks are container-independent. - - parameter generator: Generator which uses this object - - parameter container: Unused + - Parameter generator: Generator which uses this object + - Parameter container: Unused - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { generator.layout.heights.content = generator.columnState.getWrapColumnsHeight(for: container) stayOnSamePage = false @@ -65,12 +59,12 @@ internal class PDFPageBreakObject: PDFRenderObject { Creates a new page in the PDF context. Draws debug page overlay on newly created page - - parameter generator: Generator which uses this object - - parameter container: Unused + - Parameter generator: Generator which uses this object + - Parameter container: Unused - - throws: None + - Throws: None */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { if !stayOnSamePage { PDFContextGraphics.endPDFPage(in: context) PDFContextGraphics.beginPDFPage(in: context, for: generator.document.layout.bounds) @@ -83,10 +77,8 @@ internal class PDFPageBreakObject: PDFRenderObject { applyAttributes(in: context) } - /** - Creates a new `PDFPageBreakObject` - */ - override internal var copy: PDFRenderObject { + /// nodoc + override var copy: PDFRenderObject { PDFPageBreakObject() } } diff --git a/Source/Internal/Layout/PDFPageLayout+Equatable.swift b/Source/Internal/Layout/PDFPageLayout+Equatable.swift index 44e2fe68..192c2bb1 100644 --- a/Source/Internal/Layout/PDFPageLayout+Equatable.swift +++ b/Source/Internal/Layout/PDFPageLayout+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 04/11/2017. // -/** - TODO: documentation - */ extension PDFPageLayout: Equatable { - - /** - TODO: documentation - */ + /// nodoc public static func == (lhs: PDFPageLayout, rhs: PDFPageLayout) -> Bool { guard lhs.size == rhs.size else { return false diff --git a/Source/Internal/Layout/PDFSectionColumnContainer.swift b/Source/Internal/Layout/PDFSectionColumnContainer.swift index b2799006..689d6343 100644 --- a/Source/Internal/Layout/PDFSectionColumnContainer.swift +++ b/Source/Internal/Layout/PDFSectionColumnContainer.swift @@ -1,5 +1,5 @@ // -// PDFSectionContainer.swift +// PDFSectionColumnContainer.swift // TPPDF // // Created by Marco Betschart on 05.05.18. @@ -9,7 +9,6 @@ A section container defines the position of an element in a column of a given container. */ public enum PDFSectionColumnContainer { - /** Element is in no container, only real use is as a default value */ @@ -34,14 +33,14 @@ public enum PDFSectionColumnContainer { Array of all possible containers, expect `.none`. Useful for initializing default values for each container */ - internal static var all: [PDFSectionColumnContainer] { + static var all: [PDFSectionColumnContainer] { [.left, .center, .right] } /** Returns the mapped `PDFContainer` */ - internal var contentContainer: PDFContainer { + var contentContainer: PDFContainer { switch self { case .left: return PDFContainer.contentLeft case .center: return PDFContainer.contentCenter diff --git a/Source/Internal/Layout/PDFSpaceObject.swift b/Source/Internal/Layout/PDFSpaceObject.swift index 3782edfc..e6e2852e 100644 --- a/Source/Internal/Layout/PDFSpaceObject.swift +++ b/Source/Internal/Layout/PDFSpaceObject.swift @@ -6,45 +6,44 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Empty space between two elements */ -internal class PDFSpaceObject: PDFRenderObject { - +class PDFSpaceObject: PDFRenderObject { /** Height of space object in points */ - internal var space: CGFloat + var space: CGFloat /** Initializer - - parameter space: Height of space object + - Parameter space: Height of space object */ - internal init(space: CGFloat) { + init(space: CGFloat) { self.space = space } /** Creates a spacing object in the given `generator` in the given `container` - - parameter generator: Generator which uses this object - - parameter container: Container where this object is in + - Parameter generator: Generator which uses this object + - Parameter container: Container where this object is in - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var size = PDFCalculations.calculateAvailableFrame(for: generator, in: container) size.height = min(space, size.height) let position = PDFCalculations.calculateElementPosition(for: generator, in: container, with: frame.size) - self.frame = CGRect(origin: position, size: size) + frame = CGRect(origin: position, size: size) generator.layout.heights.add(space, to: container) var result: [PDFLocatedRenderObject] = [(container, self)] @@ -57,15 +56,15 @@ internal class PDFSpaceObject: PDFRenderObject { /** If `generator.debug` is enabled, this will draw a green rectangle with red border into the current context. - - parameter generator: Unused - - parameter container: Unused + - Parameter generator: Unused + - Parameter container: Unused - - throws: None + - Throws: None */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { if generator.debug { PDFGraphics.drawRect(in: context, - rect: self.frame, + rect: frame, outline: PDFLineStyle(type: .dashed, color: .red, width: 1.0), pattern: PDFGraphics.FillPattern.dotted(foreColor: .green, backColor: .white)) } @@ -75,7 +74,7 @@ internal class PDFSpaceObject: PDFRenderObject { /** Creates a new `PDFSpaceObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFSpaceObject(space: self.space) + override var copy: PDFRenderObject { + PDFSpaceObject(space: space) } } diff --git a/Source/Internal/List/PDFListObject.swift b/Source/Internal/List/PDFListObject.swift index 88cbc142..caa74153 100644 --- a/Source/Internal/List/PDFListObject.swift +++ b/Source/Internal/List/PDFListObject.swift @@ -5,27 +5,15 @@ // Created by Philip Niedertscheider on 12/08/2017. // -/** - TODO: documentation - */ -internal class PDFListObject: PDFRenderObject { +class PDFListObject: PDFRenderObject { + var list: PDFList - /** - TODO: documentation - */ - internal var list: PDFList - - /** - TODO: documentation - */ - internal init(list: PDFList) { + init(list: PDFList) { self.list = list } - /** - TODO: documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] let originalLeftIndent = generator.layout.indentation.leftIn(container: container) @@ -47,12 +35,11 @@ internal class PDFListObject: PDFRenderObject { return result } - /** - TODO: Documentation - */ - private func createSymbolItem(generator: PDFGenerator, - container: PDFContainer, - symbol: PDFListItemSymbol) throws -> [PDFLocatedRenderObject] { + private func createSymbolItem( + generator: PDFGenerator, + container: PDFContainer, + symbol: PDFListItemSymbol + ) throws -> [PDFLocatedRenderObject] { let symbol: String = symbol.stringValue let symbolText = PDFSimpleText(text: symbol) let symbolTextObject = PDFAttributedTextObject(simpleText: symbolText) @@ -74,10 +61,8 @@ internal class PDFListObject: PDFRenderObject { return try itemTextObject.calculate(generator: generator, container: container) } - /** - Creates a new `PDFListObject` with the same properties - */ - override internal var copy: PDFRenderObject { - PDFListObject(list: self.list.copy) + /// nodoc + override var copy: PDFRenderObject { + PDFListObject(list: list.copy) } } diff --git a/Source/Internal/Math/CGPoint+Math.swift b/Source/Internal/Math/CGPoint+Math.swift index 99faf771..055fc765 100644 --- a/Source/Internal/Math/CGPoint+Math.swift +++ b/Source/Internal/Math/CGPoint+Math.swift @@ -6,59 +6,57 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -extension CGPoint { - +public extension CGPoint { /** Adds a vector to a point - - parameter lhs: CGPoint - - parameter rhs: CGVector + - Parameter lhs: CGPoint + - Parameter rhs: CGVector - - returns: Translated point + - Returns: Translated point */ - public static func + (lhs: CGPoint, rhs: CGVector) -> CGPoint { + static func + (lhs: CGPoint, rhs: CGVector) -> CGPoint { CGPoint(x: lhs.x + rhs.dx, y: lhs.y + rhs.dy) } /** Adds two points together, by adding their components. - - parameter lhs: CGPoint - - parameter rhs: CGPoint + - Parameter lhs: CGPoint + - Parameter rhs: CGPoint - - returns: Added point + - Returns: Added point */ - public static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint { + static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint { CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y) } /** Subtracts two points from each other, by subtracting their components. - - parameter lhs: CGPoint - - parameter rhs: CGPoint + - Parameter lhs: CGPoint + - Parameter rhs: CGPoint - - returns: Subtracted point + - Returns: Subtracted point */ - public static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint { + static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint { CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y) } /** Adds a value to both components of a point - - parameter lhs: Point - - parameter value: Value + - Parameter lhs: Point + - Parameter value: Value - - returns: Moved point + - Returns: Moved point */ - public static func + (lhs: CGPoint, value: CGFloat) -> CGPoint { + static func + (lhs: CGPoint, value: CGFloat) -> CGPoint { CGPoint(x: lhs.x + value, y: lhs.y + value) } - } diff --git a/Source/Internal/Math/CGPoint+Null.swift b/Source/Internal/Math/CGPoint+Null.swift index aaf95d62..77f3d8e8 100644 --- a/Source/Internal/Math/CGPoint+Null.swift +++ b/Source/Internal/Math/CGPoint+Null.swift @@ -6,14 +6,13 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif extension CGPoint { - - internal static var null: CGPoint { + static var null: CGPoint { CGPoint(x: CGFloat.infinity, y: CGFloat.infinity) } } diff --git a/Source/Internal/PDFGenerator+Debug.swift b/Source/Internal/PDFGenerator+Debug.swift index 75346cea..8c59f572 100644 --- a/Source/Internal/PDFGenerator+Debug.swift +++ b/Source/Internal/PDFGenerator+Debug.swift @@ -6,22 +6,21 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Adds UI debugging information while rendering. */ extension PDFGenerator { - // MARK: - INTERNAL FUNCSs /** Overlays horizontal and vertical lines at margin insets */ - internal func drawDebugPageOverlay(in context: PDFContext) { + func drawDebugPageOverlay(in context: PDFContext) { // Only render if debugging is enabled guard debug else { return @@ -50,19 +49,28 @@ extension PDFGenerator { /** Draws a horizontal line over the whole page at the given vertical position - - parameter positionY: Position in points, from top page edge + - Parameter positionY: Position in points, from top page edge */ private func drawHorizontalMarginLines(in context: PDFContext, positionY: CGFloat) { - PDFGraphics.drawLine(in: context, start: CGPoint(x: 0, y: positionY), end: CGPoint(x: document.layout.width, y: positionY), style: debugLineStyle) + PDFGraphics.drawLine( + in: context, + start: CGPoint(x: 0, y: positionY), + end: CGPoint(x: document.layout.width, y: positionY), + style: debugLineStyle + ) } /** Draws a vertical line over the whole page at the given horizontal position - - parameter positionX: Position in points, from left page edge + - Parameter positionX: Position in points, from left page edge */ private func drawVerticalMarginLines(in context: PDFContext, positionX: CGFloat) { - PDFGraphics.drawLine(in: context, start: CGPoint(x: positionX, y: 0), end: CGPoint(x: positionX, y: document.layout.height), style: debugLineStyle) + PDFGraphics.drawLine( + in: context, + start: CGPoint(x: positionX, y: 0), + end: CGPoint(x: positionX, y: document.layout.height), + style: debugLineStyle + ) } - } diff --git a/Source/Internal/PDFGenerator+Layout.swift b/Source/Internal/PDFGenerator+Layout.swift index f7c888ac..925daa16 100644 --- a/Source/Internal/PDFGenerator+Layout.swift +++ b/Source/Internal/PDFGenerator+Layout.swift @@ -1,40 +1,38 @@ // -// PDFSingleDocumentGenerator+Layout.swift +// PDFGenerator+Layout.swift // TPPDF // // Created by Philip Niedertscheider on 13/06/2017. // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Extends the generator with shorthand methods for accessing and modifying the layout + * Extends the generator with shorthand methods for accessing and modifying the layout */ extension PDFGenerator { - /** - Get content offset of the given `container` - - - parameter container: Container where the offset is requested - - - returns: Offset in points + * Get content offset of the given `container` + * + * - Parameter container: Container where the offset is requested + * + * - Returns: Offset in points */ - internal func getContentOffset(in container: PDFContainer) -> CGFloat { + func getContentOffset(in container: PDFContainer) -> CGFloat { layout.getContentOffset(in: container) } /** - Set a content offset to a value of a given container - - - parameter container: Container where the offset is set - - parameter value: Offset value + * Set a content offset to a value of a given container + * + * - Parameter container: Container where the offset is set + * - Parameter value: Offset value */ - internal func setContentOffset(in container: PDFContainer, to value: CGFloat) { + func setContentOffset(in container: PDFContainer, to value: CGFloat) { layout.setContentOffset(in: container, to: value) } - } diff --git a/Source/Internal/Pagination/Int+RomanNumerals.swift b/Source/Internal/Pagination/Int+RomanNumerals.swift index 4a866308..1ae99174 100644 --- a/Source/Internal/Pagination/Int+RomanNumerals.swift +++ b/Source/Internal/Pagination/Int+RomanNumerals.swift @@ -1,5 +1,5 @@ // -// Int+RomanNumeral.swift +// Int+RomanNumerals.swift // TPPDF // // Created by Philip Niedertscheider on 04/11/2017. @@ -9,11 +9,10 @@ Extends an integer with conversion to Roman Numerals */ extension Int { - /** Converts `self` into a string of roman numerals. */ - internal var romanNumerals: String { + var romanNumerals: String { let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] diff --git a/Source/Internal/Pagination/PDFPagination+Equatable.swift b/Source/Internal/Pagination/PDFPagination+Equatable.swift index 84eb91e6..b1d40a62 100644 --- a/Source/Internal/Pagination/PDFPagination+Equatable.swift +++ b/Source/Internal/Pagination/PDFPagination+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 04/11/2017. // -/** - TODO: Documentation - */ extension PDFPagination: Equatable { - - /** - TODO: Documentation - */ + /// nodoc public static func == (lhs: PDFPagination, rhs: PDFPagination) -> Bool { guard lhs.container == rhs.container else { return false diff --git a/Source/Internal/Pagination/PDFPagination.swift b/Source/Internal/Pagination/PDFPagination.swift index e3f53dba..6a88597e 100644 --- a/Source/Internal/Pagination/PDFPagination.swift +++ b/Source/Internal/Pagination/PDFPagination.swift @@ -6,16 +6,15 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Used to define the pagination behaviour of a document. */ public struct PDFPagination { - /** Container where the pagination will be placed */ @@ -45,10 +44,10 @@ public struct PDFPagination { /** Initializer - - parameter container: Container where pagination is placed, defaults to `PDFContainer.none`, meaning it won't be rendered - - parameter style: Style of pagination, defaults to `PDFPaginationStyle.default` - - parameter range: Start and end of pages which will be included - - parameter hiddenPages: List of numbers which are excluded from rendering + - Parameter container: Container where pagination is placed, defaults to `PDFContainer.none`, meaning it won't be rendered + - Parameter style: Style of pagination, defaults to `PDFPaginationStyle.default` + - Parameter range: Start and end of pages which will be included + - Parameter hiddenPages: List of numbers which are excluded from rendering */ public init(container: PDFContainer = .none, style: PDFPaginationStyle = .default, diff --git a/Source/Internal/Pagination/PDFPaginationClosure.swift b/Source/Internal/Pagination/PDFPaginationClosure.swift index 329a3b4a..c675de5f 100644 --- a/Source/Internal/Pagination/PDFPaginationClosure.swift +++ b/Source/Internal/Pagination/PDFPaginationClosure.swift @@ -8,9 +8,9 @@ /** Closure for custom pagination formatting. - - parameter page: `Int` - Current page number - - parameter total: `Int` - Total amount of pages + - Parameter page: `Int` - Current page number + - Parameter total: `Int` - Total amount of pages - - returns: Formatted pagination string + - Returns: Formatted pagination string */ public typealias PDFPaginationClosure = (_ page: Int, _ total: Int) -> String diff --git a/Source/Internal/Pagination/PDFPaginationStyle+Equatable.swift b/Source/Internal/Pagination/PDFPaginationStyle+Equatable.swift index e7f3399c..f9c05fcf 100644 --- a/Source/Internal/Pagination/PDFPaginationStyle+Equatable.swift +++ b/Source/Internal/Pagination/PDFPaginationStyle+Equatable.swift @@ -5,14 +5,8 @@ // Created by Philip Niedertscheider on 04/11/2017. // -/** - TODO: Documentation - */ extension PDFPaginationStyle: Equatable { - - /** - TODO: Documentation - */ + /// nodoc public static func == (lhs: PDFPaginationStyle, rhs: PDFPaginationStyle) -> Bool { if case PDFPaginationStyle.default = lhs, case PDFPaginationStyle.default = rhs { return true @@ -23,11 +17,11 @@ extension PDFPaginationStyle: Equatable { } if case let PDFPaginationStyle.customNumberFormat(lhsTemplate, lhsFormatter) = lhs, - case let PDFPaginationStyle.customNumberFormat(rhsTemplate, rhsFormatter) = rhs { + case let PDFPaginationStyle.customNumberFormat(rhsTemplate, rhsFormatter) = rhs { return lhsTemplate == rhsTemplate && lhsFormatter == rhsFormatter } - if case PDFPaginationStyle.customClosure(_) = lhs, case PDFPaginationStyle.customClosure(_) = rhs { + if case PDFPaginationStyle.customClosure = lhs, case PDFPaginationStyle.customClosure = rhs { // Always return false if a custom closure is used // https://stackoverflow.com/questions/24111984/how-do-you-test-functions-and-closures-for-equality return false @@ -35,5 +29,4 @@ extension PDFPaginationStyle: Equatable { return false } - } diff --git a/Source/Internal/Pagination/PDFPaginationStyle.swift b/Source/Internal/Pagination/PDFPaginationStyle.swift index 83ace3dc..339dca0d 100644 --- a/Source/Internal/Pagination/PDFPaginationStyle.swift +++ b/Source/Internal/Pagination/PDFPaginationStyle.swift @@ -6,9 +6,9 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** @@ -17,7 +17,6 @@ import AppKit Enums using a template String as parameter will replace the first instance of `%@` with the index and the second one with the total amount of pages. */ public enum PDFPaginationStyle { - /** Default format, concats current page and total pages with a dash. @@ -28,15 +27,15 @@ public enum PDFPaginationStyle { /** Returns pagination in roman numerals. - - parameter template: Template `String`, instances of `%@` will be replaced. + - Parameter template: Template `String`, instances of `%@` will be replaced. */ case roman(template: String) /** Formats pagination numbers using the `formatter` and formatting the string using the given `template`. - - parameter template: Template string where `$@` is replaced - - parameter formatter: Number formatter + - Parameter template: Template string where `$@` is replaced + - Parameter formatter: Number formatter */ case customNumberFormat(template: String, formatter: NumberFormatter) @@ -48,26 +47,26 @@ public enum PDFPaginationStyle { /** Creates formatted pagination string. - - parameter page: `Int` - Current page - - parameter total: `Int` - Total amount of pages. + - Parameter page: `Int` - Current page + - Parameter total: `Int` - Total amount of pages. - - returns: Formatted `String` + - Returns: Formatted `String` */ public func format(page: Int, total: Int) -> String { switch self { case .default: return String(format: "%@ - %@", String(page), String(total)) - case .roman(let template): + case let .roman(template): let romanIndex = page.romanNumerals let romanMax = total.romanNumerals return String(format: template, romanIndex, romanMax) - case .customNumberFormat(let template, let formatter): + case let .customNumberFormat(template, formatter): let indexString = formatter.string(from: page as NSNumber)! let maxString = formatter.string(from: total as NSNumber)! return String(format: template, indexString, maxString) - case .customClosure(let closure): + case let .customClosure(closure): return closure(page, total) } } diff --git a/Source/Internal/Section/PDFColumnWrapSectionObject.swift b/Source/Internal/Section/PDFColumnWrapSectionObject.swift index aa2716a2..df6bddda 100644 --- a/Source/Internal/Section/PDFColumnWrapSectionObject.swift +++ b/Source/Internal/Section/PDFColumnWrapSectionObject.swift @@ -6,59 +6,27 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ -internal class PDFColumnWrapSectionObject: PDFRenderObject { +class PDFColumnWrapSectionObject: PDFRenderObject { + var columns: Int + var widths: [CGFloat] + var spacings: [CGFloat] + var isDisable: Bool + var addPageBreak: Bool - /** - TODO: Documentation - */ - internal var columns: Int - - /** - TODO: Documentation - */ - internal var widths: [CGFloat] - - /** - TODO: Documentation - */ - internal var spacings: [CGFloat] - - /** - TODO: Documentation - */ - internal var isDisable: Bool - - /** - TODO: Documentation - */ - internal var addPageBreak: Bool - - /** - TODO: Documentation - */ - internal convenience init(columns: Int, widths: [CGFloat], spacings: [CGFloat]) { + convenience init(columns: Int, widths: [CGFloat], spacings: [CGFloat]) { self.init(columns: columns, widths: widths, spacings: spacings, isDisable: false, addPageBreak: false) } - /** - TODO: Documentation - */ - internal convenience init(isDisable: Bool, addPageBreak: Bool) { + convenience init(isDisable: Bool, addPageBreak: Bool) { self.init(columns: 0, widths: [], spacings: [], isDisable: isDisable, addPageBreak: addPageBreak) } - /** - TODO: Documentation - */ - internal init(columns: Int, widths: [CGFloat], spacings: [CGFloat], isDisable: Bool, addPageBreak: Bool) { + init(columns: Int, widths: [CGFloat], spacings: [CGFloat], isDisable: Bool, addPageBreak: Bool) { self.columns = columns self.widths = widths self.spacings = spacings @@ -69,13 +37,13 @@ internal class PDFColumnWrapSectionObject: PDFRenderObject { /** Modifies the layout of the given `generator`. - - parameter generator: Generator which uses this object - - parameter container: Container where this object is located + - Parameter generator: Generator which uses this object + - Parameter container: Container where this object is located - - returns: Self + - Returns: Self */ @discardableResult - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { generator.columnState.set(currentColumn: 0, for: container) generator.columnState.set(inset: (0, 0), for: container) @@ -107,14 +75,14 @@ internal class PDFColumnWrapSectionObject: PDFRenderObject { return [(container, self)] } - /** - TODO: Documentation - */ - override internal var copy: PDFRenderObject { - PDFColumnWrapSectionObject(columns: self.columns, - widths: self.widths, - spacings: self.spacings, - isDisable: self.isDisable, - addPageBreak: self.addPageBreak) + /// nodoc + override var copy: PDFRenderObject { + PDFColumnWrapSectionObject( + columns: columns, + widths: widths, + spacings: spacings, + isDisable: isDisable, + addPageBreak: addPageBreak + ) } } diff --git a/Source/Internal/Section/PDFSectionColumnObject.swift b/Source/Internal/Section/PDFSectionColumnObject.swift index 74267d09..d68720e1 100644 --- a/Source/Internal/Section/PDFSectionColumnObject.swift +++ b/Source/Internal/Section/PDFSectionColumnObject.swift @@ -5,40 +5,26 @@ // Created by Marco Betschart on 05.05.18. // -/** - TODO: Documentation - */ -internal class PDFSectionColumnObject: PDFRenderObject { +class PDFSectionColumnObject: PDFRenderObject { + var column: PDFSectionColumn - /** - TODO: Documentation - */ - internal var column: PDFSectionColumn + init(column: PDFSectionColumn) { + self.column = column + } - /** - TODO: Documentation - */ - internal init(column: PDFSectionColumn) { - self.column = column - } + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + var result: [PDFLocatedRenderObject] = [] - /** - TODO: Documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { - var result: [PDFLocatedRenderObject] = [] + for (container, object) in column.objects { + result += try object.calculate(generator: generator, container: container.contentContainer) + } - for (container, object) in column.objects { - result += try object.calculate(generator: generator, container: container.contentContainer) - } + return result + } - return result - } - - /** - Creates a new `PDFSectionColumnObject` with the same properties - */ - override internal var copy: PDFRenderObject { - PDFSectionColumnObject(column: self.column.copy) - } + /// nodoc + override var copy: PDFRenderObject { + PDFSectionColumnObject(column: column.copy) + } } diff --git a/Source/Internal/Section/PDFSectionObject.swift b/Source/Internal/Section/PDFSectionObject.swift index 25b85014..9ef56d47 100644 --- a/Source/Internal/Section/PDFSectionObject.swift +++ b/Source/Internal/Section/PDFSectionObject.swift @@ -6,38 +6,26 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -/** - TODO: Documentation - */ -internal class PDFSectionObject: PDFRenderObject { - - internal struct PDFSectionColumnMetadata { - internal let minX: CGFloat - internal let width: CGFloat - internal let backgroundColor: Color? +class PDFSectionObject: PDFRenderObject { + struct PDFSectionColumnMetadata { + let minX: CGFloat + let width: CGFloat + let backgroundColor: Color? } - /** - TODO: Documentation - */ - internal var section: PDFSection + var section: PDFSection - /** - TODO: Documentation - */ - internal init(section: PDFSection) { + init(section: PDFSection) { self.section = section } - /** - TODO: Documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] // Save state of layout @@ -64,9 +52,11 @@ internal class PDFSectionObject: PDFRenderObject { objectsPerColumn[columnIndex] = try PDFSectionColumnObject(column: column) .calculate(generator: generator, container: container) - columnMetadata.append(.init(minX: generator.layout.margin.left + leftColumnGuide, - width: columnWidth, - backgroundColor: column.backgroundColor)) + columnMetadata.append(.init( + minX: generator.layout.margin.left + leftColumnGuide, + width: columnWidth, + backgroundColor: column.backgroundColor + )) leftColumnGuide = rightColumnGuide + section.columnMargin } @@ -102,32 +92,38 @@ internal class PDFSectionObject: PDFRenderObject { return result } - /** The `PDFDocument` render engine calculates each object, which returns a list of calculated objects. - As an example if you add a text object, it will be calculated and return one text object which will then be rendered. - - **BUT** if the text is too long to fit the space, then it will be split up into two text objects with a `PDFPageBreakObject` in-between. - - During the render process whenever a page break object is found, it will create a new pdf page and continue there. - In order to render multi columns correctly, we need to merge the page breaks of all columns and make sure - the page break occurs at the right time: - - ``` - All objects of column 1 before the first pagebreak - All objects of column 2 before the first pagebreak - All objects of column 3 before the first pagebreak - Pagebreak - All objects of column 1 after the first pagebreak up to the next pagebreak - All objects of column 2 after the first pagebreak up to the next pagebreak - All objects of column 3 after the first pagebreak up to the next pagebreak - Pagebreak - ... - ``` + /** + * The `PDFDocument` render engine calculates each object, which returns a list of calculated objects. + * As an example if you add a text object, it will be calculated and return one text object which will then be rendered. + * + * **BUT** if the text is too long to fit the space, then it will be split up into two text objects with a `PDFPageBreakObject` in-between. + * + * During the render process whenever a page break object is found, it will create a new pdf page and continue there. + * In order to render multi columns correctly, we need to merge the page breaks of all columns and make sure + * the page break occurs at the right time: + * + * ``` + * All objects of column 1 before the first pagebreak + * All objects of column 2 before the first pagebreak + * All objects of column 3 before the first pagebreak + * Pagebreak + * All objects of column 1 after the first pagebreak up to the next pagebreak + * All objects of column 2 after the first pagebreak up to the next pagebreak + * All objects of column 3 after the first pagebreak up to the next pagebreak + * Pagebreak + * ... + * ``` */ - internal func calulatePageBreakPositions(_ objectsPerColumn: [Int: [PDFLocatedRenderObject]], metadata: [PDFSectionColumnMetadata], container: PDFContainer) -> [PDFLocatedRenderObject] { + func calulatePageBreakPositions( // swiftlint:disable:this cyclomatic_complexity function_body_length + _ objectsPerColumn: [Int: [PDFLocatedRenderObject]], + metadata: [PDFSectionColumnMetadata], + container: PDFContainer + ) -> [PDFLocatedRenderObject] { // stores how many objects are in one column at max let maxObjectsPerColumn = objectsPerColumn.reduce(0) { max($0, $1.value.count) } - /* as soon as a column requests a page break, we need to stack subsequent objects of the very same column until the following is `true`: + /* + * as soon as a column requests a page break, we need to stack subsequent objects of the very same column until the following is `true`: * one or more columns do not have more objects and all other columns, which have more objects left, are requesting a page break */ var stackedObjectsPerColumn = [Int: [PDFLocatedRenderObject]]() @@ -159,13 +155,11 @@ internal class PDFSectionObject: PDFRenderObject { } } - // swiftlint:disable multiline_function_chains let allFrames = resultPerColumn.values.reduce([], +) .map(\.1.frame) - .filter({ $0.origin != .null }) + .filter { $0.origin != .null } if let sectionMinY = allFrames.map({ $0.minY }).min(), - let sectionMaxY = allFrames.map({ $0.maxY }).max() { - + let sectionMaxY = allFrames.map({ $0.maxY }).max() { for (idx, columnObjects) in resultPerColumn { let met = metadata[idx] guard let backgroundColor = met.backgroundColor else { @@ -218,10 +212,8 @@ internal class PDFSectionObject: PDFRenderObject { return result } - /** - Creates a new `PDFSectionObject` with the same properties - */ - override internal var copy: PDFRenderObject { - PDFSectionObject(section: self.section.copy) + /// nodoc + override var copy: PDFRenderObject { + PDFSectionObject(section: section.copy) } } diff --git a/Source/Internal/Table Of Content/PDFTableOfContentObject.swift b/Source/Internal/Table Of Content/PDFTableOfContentObject.swift index 88cad6b2..ada32f31 100644 --- a/Source/Internal/Table Of Content/PDFTableOfContentObject.swift +++ b/Source/Internal/Table Of Content/PDFTableOfContentObject.swift @@ -7,33 +7,17 @@ import Foundation -/** - TODO: Documentation - */ -internal class PDFTableOfContentObject: PDFRenderObject { +class PDFTableOfContentObject: PDFRenderObject { + var list: PDFList + var options: PDFTableOfContent - /** - TODO: Documentation - */ - internal var list: PDFList - - /** - TODO: Documentation - */ - internal var options: PDFTableOfContent - - /** - TODO: Documentation - */ - internal init(list: PDFList, options: PDFTableOfContent) { + init(list: PDFList, options: PDFTableOfContent) { self.list = list self.options = options } - /** - TODO: Documentation - */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + /// nodoc + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] result += try PDFListObject(list: list).calculate(generator: generator, container: container) @@ -41,10 +25,8 @@ internal class PDFTableOfContentObject: PDFRenderObject { return result } - /** - TODO: Documentation - */ - override internal var copy: PDFRenderObject { - PDFListObject(list: self.list.copy) + /// nodoc + override var copy: PDFRenderObject { + PDFListObject(list: list.copy) } } diff --git a/Source/Internal/Table/PDFTableCalculatedCell.swift b/Source/Internal/Table/PDFTableCalculatedCell.swift index 3129735c..638787b8 100644 --- a/Source/Internal/Table/PDFTableCalculatedCell.swift +++ b/Source/Internal/Table/PDFTableCalculatedCell.swift @@ -7,7 +7,7 @@ import CoreGraphics -internal struct PDFTableCalculatedCell { +struct PDFTableCalculatedCell { var cell: PDFTableCell var type: PDFTableObject.CellType var style: PDFTableCellStyle diff --git a/Source/Internal/Table/PDFTableMergeUtil.swift b/Source/Internal/Table/PDFTableMergeUtil.swift index 12caa6f5..c7aa0f67 100644 --- a/Source/Internal/Table/PDFTableMergeUtil.swift +++ b/Source/Internal/Table/PDFTableMergeUtil.swift @@ -7,13 +7,12 @@ import Foundation -internal enum PDFTableMergeUtil { - - internal static func calculateMerged(table: PDFTable) -> [[PDFTableNode]] { - guard table.size.rows > 0 && table.size.columns > 0 else { +enum PDFTableMergeUtil { + static func calculateMerged(table: PDFTable) -> [[PDFTableNode]] { + guard table.size.rows > 0, table.size.columns > 0 else { return [] } - var found = table.cells.map({ $0.map({ _ in false }) }) + var found = table.cells.map { $0.map { _ in false } } var rows: [[PDFTableNode]] = [] // Iterate all rows diff --git a/Source/Internal/Table/PDFTableNode.swift b/Source/Internal/Table/PDFTableNode.swift index 250049f2..0f71b333 100644 --- a/Source/Internal/Table/PDFTableNode.swift +++ b/Source/Internal/Table/PDFTableNode.swift @@ -7,15 +7,14 @@ import Foundation -internal class PDFTableNode { +class PDFTableNode { + let cell: PDFTableCell + let position: PDFTableCellPosition - internal let cell: PDFTableCell - internal let position: PDFTableCellPosition + var moreRowsSpan: Int = 0 + var moreColumnsSpan: Int = 0 - internal var moreRowsSpan: Int = 0 - internal var moreColumnsSpan: Int = 0 - - internal init(cell: PDFTableCell, position: PDFTableCellPosition) { + init(cell: PDFTableCell, position: PDFTableCellPosition) { self.cell = cell self.position = position } diff --git a/Source/Internal/Table/PDFTableObject.swift b/Source/Internal/Table/PDFTableObject.swift index d912c3d1..4d631d7f 100644 --- a/Source/Internal/Table/PDFTableObject.swift +++ b/Source/Internal/Table/PDFTableObject.swift @@ -6,36 +6,35 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -// swiftlint:disable function_parameter_count +// swiftlint:disable function_parameter_count file_length type_body_length function_body_length /** Internal object, used for calculating a `PDFTable` */ -internal class PDFTableObject: PDFRenderObject { - +class PDFTableObject: PDFRenderObject { /** Reference to table */ - internal var table: PDFTable + var table: PDFTable /** Initializer - - parameter table: Table to calculate and draw + - Parameter table: Table to calculate and draw */ - internal init(table: PDFTable) { + init(table: PDFTable) { self.table = table } /** - - throws: `PDFError` if table validation fails. See `PDFTableValidator.validateTableData(::)` for details + - Throws: `PDFError` if table validation fails. See `PDFTableValidator.validateTableData(::)` for details */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { try PDFTableValidator.validateTable(table: table) // Calculate available size on current page @@ -117,11 +116,11 @@ internal class PDFTableObject: PDFRenderObject { rowIdx = table.size.rows - 1 } - headerHeight = cells[rowIdx].reduce(0, { (prev, calcCell) in + headerHeight = cells[rowIdx].reduce(0) { prev, calcCell in max(prev, calcCell.frames.cell.minY) - }) - headerCells.reduce(CGFloat.greatestFiniteMagnitude, { (prev, calcCell) in + } - headerCells.reduce(CGFloat.greatestFiniteMagnitude) { prev, calcCell in min(prev, calcCell.frames.cell.minY) - }) + } } // Create render objects @@ -138,13 +137,13 @@ internal class PDFTableObject: PDFRenderObject { return renderObjects.objects } - internal func calculate(generator: PDFGenerator, - container: PDFContainer, - cell: PDFTableCell, - style: PDFTableCellStyle, - type: CellType, - origin: CGPoint, - width: CGFloat) -> PDFTableCalculatedCell { + func calculate(generator: PDFGenerator, + container: PDFContainer, + cell: PDFTableCell, + style: PDFTableCellStyle, + type: CellType, + origin: CGPoint, + width: CGFloat) -> PDFTableCalculatedCell { var frame = PDFTableCalculatedCell( cell: cell, type: type, @@ -184,13 +183,13 @@ internal class PDFTableObject: PDFRenderObject { return frame } - internal func calculate(content: PDFTableContent, - style: PDFTableCellStyle, - cell: PDFTableCell, - generator: PDFGenerator, - container: PDFContainer, - contentOrigin: CGPoint, - contentWidth: CGFloat) -> CGRect { + func calculate(content: PDFTableContent, + style: PDFTableCellStyle, + cell: PDFTableCell, + generator: PDFGenerator, + container: PDFContainer, + contentOrigin: CGPoint, + contentWidth: CGFloat) -> CGRect { if let text = getAttributedStringOfTable(content: content, style: style, alignment: cell.alignment) { return PDFCalculations .calculateCellFrame(generator: generator, @@ -209,16 +208,16 @@ internal class PDFTableObject: PDFRenderObject { return CGRect.zero } - internal func getAttributedStringOfTable(content: PDFTableContent, - style: PDFTableCellStyle, - alignment: PDFTableCellAlignment) -> NSAttributedString? { + func getAttributedStringOfTable(content: PDFTableContent, + style: PDFTableCellStyle, + alignment: PDFTableCellAlignment) -> NSAttributedString? { if let stringText = content.stringValue { return createAttributedCellText(text: stringText, cellStyle: style, alignment: alignment) } return content.attributedStringValue } - internal func reposition(cell: PDFTableCalculatedCell) -> PDFTableCalculatedCell { + func reposition(cell: PDFTableCalculatedCell) -> PDFTableCalculatedCell { var result = cell result.frames.content.origin.x = repositionX(of: cell) @@ -227,7 +226,7 @@ internal class PDFTableObject: PDFRenderObject { return result } - internal func repositionX(of calculatedCell: PDFTableCalculatedCell) -> CGFloat { + func repositionX(of calculatedCell: PDFTableCalculatedCell) -> CGFloat { let alignment = calculatedCell.cell.alignment let frame = calculatedCell.frames @@ -240,7 +239,7 @@ internal class PDFTableObject: PDFRenderObject { return frame.content.minX + (frame.cell.width - 2 * table.padding - frame.content.width) / 2 } - internal func repositionY(of calculatedCell: PDFTableCalculatedCell ) -> CGFloat { + func repositionY(of calculatedCell: PDFTableCalculatedCell) -> CGFloat { let alignment = calculatedCell.cell.alignment let frame = calculatedCell.frames @@ -253,10 +252,7 @@ internal class PDFTableObject: PDFRenderObject { return frame.content.minY + (frame.cell.height - 2 * table.padding - frame.content.height) / 2 } - /** - TODO: Documentation - */ - internal func createAttributedCellText(text: String, cellStyle: PDFTableCellStyle, alignment: PDFTableCellAlignment) -> NSAttributedString { + func createAttributedCellText(text: String, cellStyle: PDFTableCellStyle, alignment: PDFTableCellAlignment) -> NSAttributedString { let paragraph = NSMutableParagraphStyle() paragraph.alignment = { if alignment.isLeft { @@ -276,14 +272,13 @@ internal class PDFTableObject: PDFRenderObject { return NSAttributedString(string: text, attributes: attributes) } - /** - TODO: Documentation - */ - internal func createRenderObjects(generator: PDFGenerator, - container: PDFContainer, - cells: [PDFTableCalculatedCell], - headerCells: [PDFTableCalculatedCell]?, - headerHeight: CGFloat) throws -> (objects: [PDFLocatedRenderObject], offset: CGFloat) { + func createRenderObjects( // swiftlint:disable:this cyclomatic_complexity + generator: PDFGenerator, + container: PDFContainer, + cells: [PDFTableCalculatedCell], + headerCells: [PDFTableCalculatedCell]?, + headerHeight: CGFloat + ) throws -> (objects: [PDFLocatedRenderObject], offset: CGFloat) { var result: [PDFLocatedRenderObject] = [] var firstPage = true @@ -318,27 +313,31 @@ internal class PDFTableObject: PDFRenderObject { cellElements += [createCellBackgroundObject(style: item.style, frame: cellFrame)] // Content - if let contentObj = createCellContentObject(content: item.cell.content, - style: item.style, - alignment: item.cell.alignment, - frame: contentFrame) { + if let contentObj = createCellContentObject( + content: item.cell.content, + style: item.style, + alignment: item.cell.alignment, + frame: contentFrame + ) { cellElements.append(contentObj) } // Grid let outline = try createCellOutlineObjects(borders: item.style.borders, frame: cellFrame) - .map({ try $0.calculate(generator: generator, container: container) }) + .map { try $0.calculate(generator: generator, container: container) } .reduce([], +) .map(\.1) cellElements += outline - let sliceObject = createSliceObject(frame: cellFrame, - elements: cellElements, - minOffset: minOffset, - maxOffset: maxOffset) + let sliceObject = createSliceObject( + frame: cellFrame, + elements: cellElements, + minOffset: minOffset, + maxOffset: maxOffset + ) result += try sliceObject.calculate(generator: generator, container: container) } - minOffset += headerHeight + minOffset += headerHeight } if !firstPage { // shift the rest of the cells down by headerHeight @@ -350,12 +349,15 @@ internal class PDFTableObject: PDFRenderObject { nextPageCells = shiftCellsBy(cells: nextPageCells, shiftValue: table.margin) } - let filterResult = filterCellsOnPage(for: generator, items: nextPageCells, - minOffset: minOffset, maxOffset: maxOffset, - shouldSplitCellsOnPageBreak: table.shouldSplitCellsOnPageBreak) + let filterResult = filterCellsOnPage( + for: generator, items: nextPageCells, + minOffset: minOffset, maxOffset: maxOffset, + shouldSplitCellsOnPageBreak: table.shouldSplitCellsOnPageBreak + ) let onPageCells = filterResult.cells nextPageCells = filterResult.remainder - // If none of the cells fit on the current page, the algorithm will try again on the next page and if it occurs again, an error should be thrown + // If none of the cells fit on the current page, the algorithm will try again on the next page + // and if it occurs again, an error should be thrown if onPageCells.isEmpty && !firstPage, let firstInvalidCell = nextPageCells.first { throw PDFError.tableCellTooBig(cell: firstInvalidCell.cell) } @@ -383,7 +385,7 @@ internal class PDFTableObject: PDFRenderObject { // Grid let outline = try createCellOutlineObjects(borders: item.style.borders, frame: cellFrame) - .map({ try $0.calculate(generator: generator, container: container) }) + .map { try $0.calculate(generator: generator, container: container) } .reduce([], +) .map(\.1) cellElements += outline @@ -415,7 +417,7 @@ internal class PDFTableObject: PDFRenderObject { } /// Holds two lists of cells, used during table calculations - internal struct FilteredCells { + struct FilteredCells { /// List of calculated cells on the active page var cells: [PDFTableCalculatedCell] /// List of remaining cells on further pages @@ -431,7 +433,13 @@ internal class PDFTableObject: PDFRenderObject { /// - maxOffset: Maximum `y`-position on the page /// - shouldSplitCellsOnPageBreak: If `true`, cells won't be sliced and shown on both pages, instead moved entirely to the next page /// - Returns: Two lists of cells, see `FilteredCells` - internal func filterCellsOnPage(for generator: PDFGenerator, items: [PDFTableCalculatedCell], minOffset: CGFloat, maxOffset: CGFloat, shouldSplitCellsOnPageBreak: Bool) -> FilteredCells { + func filterCellsOnPage( + for _: PDFGenerator, + items: [PDFTableCalculatedCell], + minOffset: CGFloat, + maxOffset: CGFloat, + shouldSplitCellsOnPageBreak: Bool + ) -> FilteredCells { // Maximum height available let contentHeight = maxOffset - minOffset var result = FilteredCells(cells: [], remainder: []) @@ -468,9 +476,9 @@ internal class PDFTableObject: PDFRenderObject { return result } - internal typealias ShiftedCells = [PDFTableCalculatedCell] + typealias ShiftedCells = [PDFTableCalculatedCell] - internal func shiftCellsBy(cells: [PDFTableCalculatedCell], shiftValue: CGFloat) -> ShiftedCells { + func shiftCellsBy(cells: [PDFTableCalculatedCell], shiftValue: CGFloat) -> ShiftedCells { var shiftedCells: [PDFTableCalculatedCell] = [] for cell in cells { @@ -483,7 +491,7 @@ internal class PDFTableObject: PDFRenderObject { return shiftedCells } - internal func createSliceObject(frame: CGRect, elements: [PDFRenderObject], minOffset: CGFloat, maxOffset: CGFloat) -> PDFSlicedObject { + func createSliceObject(frame: CGRect, elements: [PDFRenderObject], minOffset: CGFloat, maxOffset: CGFloat) -> PDFSlicedObject { let sliceObject = PDFSlicedObject(children: elements, frame: frame) if frame.maxY > maxOffset { sliceObject.frame.size.height -= sliceObject.frame.maxY - maxOffset @@ -502,7 +510,7 @@ internal class PDFTableObject: PDFRenderObject { /// - style: Style of table cell /// - frame: Frame of cell /// - Returns: Calculated `PDFRectangleObject` - internal func createCellBackgroundObject(style: PDFTableCellStyle, frame: CGRect) -> PDFRenderObject { + func createCellBackgroundObject(style: PDFTableCellStyle, frame: CGRect) -> PDFRenderObject { let object = PDFRectangleObject(lineStyle: .none, size: frame.size, fillColor: style.colors.fill) object.frame = frame return object @@ -511,8 +519,8 @@ internal class PDFTableObject: PDFRenderObject { /** Creates the render object for the cell content */ - internal func createCellContentObject(content: PDFTableContent?, style: PDFTableCellStyle, - alignment: PDFTableCellAlignment, frame: CGRect) -> PDFRenderObject? { + func createCellContentObject(content: PDFTableContent?, style: PDFTableCellStyle, + alignment: PDFTableCellAlignment, frame: CGRect) -> PDFRenderObject? { guard let content = content else { return nil } @@ -539,18 +547,16 @@ internal class PDFTableObject: PDFRenderObject { return contentObject } - internal enum CellType: Equatable { - + enum CellType: Equatable { case header case footer case rowHeader case alternatingRow case content case custom(style: PDFTableCellStyle) - } - internal func getCellType(of node: PDFTableNode, in table: PDFTable, at rowIdx: Int) -> CellType { + func getCellType(of node: PDFTableNode, in table: PDFTable, at rowIdx: Int) -> CellType { if let style = node.cell.style { return .custom(style: style) } @@ -574,7 +580,7 @@ internal class PDFTableObject: PDFRenderObject { /// - tableStyle: Style configuration of table /// - type: Type of cell /// - Returns: Style of cell - internal func getStyle(tableStyle: PDFTableStyle, type: CellType) -> PDFTableCellStyle { + func getStyle(tableStyle: PDFTableStyle, type: CellType) -> PDFTableCellStyle { switch type { case .header: return tableStyle.columnHeaderStyle @@ -584,7 +590,7 @@ internal class PDFTableObject: PDFRenderObject { return tableStyle.rowHeaderStyle case .alternatingRow: return tableStyle.alternatingContentStyle ?? tableStyle.contentStyle - case .custom(let style): + case let .custom(style): return style default: return tableStyle.contentStyle @@ -596,7 +602,7 @@ internal class PDFTableObject: PDFRenderObject { /// - borders: Style of each border edge /// - frame: Frame of rectangle /// - Returns: Array of `PDFLineObject` - internal func createCellOutlineObjects(borders: PDFTableCellBorders, frame: CGRect) -> [PDFLineObject] { + func createCellOutlineObjects(borders: PDFTableCellBorders, frame: CGRect) -> [PDFLineObject] { [ PDFLineObject(style: borders.top, startPoint: CGPoint(x: frame.minX, y: frame.minY), @@ -614,7 +620,9 @@ internal class PDFTableObject: PDFRenderObject { } /// Creates a new `PDFTableObject` with the same properties - override internal var copy: PDFRenderObject { + override var copy: PDFRenderObject { PDFTableObject(table: table.copy) } } + +// swiftlint:enable function_parameter_count file_length type_body_length function_body_length diff --git a/Source/Internal/Table/PDFTableValidator.swift b/Source/Internal/Table/PDFTableValidator.swift index 398c332b..50eb0e43 100644 --- a/Source/Internal/Table/PDFTableValidator.swift +++ b/Source/Internal/Table/PDFTableValidator.swift @@ -6,27 +6,26 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** PDFTable validation utility */ -internal enum PDFTableValidator { - +enum PDFTableValidator { /** Validates a given `table`. If no error is thrown, validation was successfull. - - parameter table: Table for validation + - Parameter table: Table for validation - - throws: + - Throws: - `PDFError.tableIsEmpty`, if cells count is zero - should be avoided. - `PDFError`tableStructureInvalid`, if a row could not validated, see `PDFTableValidator.validateTableData(::)` */ - internal static func validateTable(table: PDFTable) throws { + static func validateTable(table: PDFTable) throws { // Throw error when empty. Signalizes developer he tries to render an empty table. Might cause format errors if table.cells.isEmpty { throw PDFError.tableIsEmpty @@ -39,7 +38,7 @@ internal enum PDFTableValidator { let column = table[column: colIdx] var prevCell = column[0] var count = 0 - while count < table.size.rows && (count < table.style.columnHeaderCount || column[count] === prevCell) { + while count < table.size.rows, count < table.style.columnHeaderCount || column[count] === prevCell { prevCell = column[count] count += 1 } @@ -61,37 +60,37 @@ internal enum PDFTableValidator { Validates the given `data`, `alignments` and `columnWidths` If no error is thrown, validation was successfull. - - parameter data: Two dimensional array of optional objects - - parameter alignments: Optional two dimensional array of alignments, defaults to `nil` - - parameter columnWidhts: Optional array of column width values + - Parameter data: Two dimensional array of optional objects + - Parameter alignments: Optional two dimensional array of alignments, defaults to `nil` + - Parameter columnWidhts: Optional array of column width values - - throws: + - Throws: - `PDFError.tableIsEmpty`, if cells count is zero - should be avoided. - `PDFError.tableStructureInvalid`, if: - data row count and alignment row count do not equal - data column count and alignment column count do not equal - data column count and column count do not equal */ - internal static func validateTableData(data: [[Any?]], alignments: [[PDFTableCellAlignment]]? = nil, columnWidths: [CGFloat]? = nil) throws { + static func validateTableData(data: [[Any?]], alignments: [[PDFTableCellAlignment]]? = nil, columnWidths: [CGFloat]? = nil) throws { // Throw error when empty. Signalizes developer he tries to render an empty table. Might cause format errors if data.isEmpty { throw PDFError.tableIsEmpty } // Throw error when data row count does not equal alignment row count - if alignments != nil && data.count != alignments!.count { + if alignments != nil, data.count != alignments!.count { throw PDFError.tableStructureInvalid(message: "Data and alignment must be equal size!") } // Compare each data row for (rowIdx, row) in data.enumerated() { // Throw error when columns count does not equal alignment columns count - if alignments != nil && row.count != alignments![rowIdx].count { + if alignments != nil, row.count != alignments![rowIdx].count { throw PDFError.tableStructureInvalid(message: "Data and alignment for row with index \(rowIdx) does not have the same amount!") } // Throw error when columns row count does not equal relativeColumnWidth count - if columnWidths != nil && row.count != columnWidths!.count { + if columnWidths != nil, row.count != columnWidths!.count { throw PDFError.tableStructureInvalid(message: "Data and widths for row with index \(rowIdx) does not have the same amount!") } } diff --git a/Source/Internal/Text/PDFAttributedTextObject.swift b/Source/Internal/Text/PDFAttributedTextObject.swift index 950dd3f2..fbedf147 100644 --- a/Source/Internal/Text/PDFAttributedTextObject.swift +++ b/Source/Internal/Text/PDFAttributedTextObject.swift @@ -6,78 +6,67 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** - Calculates and draws a text - */ -internal class PDFAttributedTextObject: PDFRenderObject { + Structure used to calculate and render text - /** - Instance of attributed text object, holds instance of `NSAttributedString` - */ - internal var attributedText: PDFAttributedText? + ``PDFSimpleText`` and ``PDFAttributedText`` are both converted into this class, using an ``NSAttributedString`` as an abstraction to ``CoreText`` + */ +class PDFAttributedTextObject: PDFRenderObject { + /// Instance of attributed text object, holds instance of `NSAttributedString` + var attributedText: PDFAttributedText? - /** - Instance of simple text object, will be converted into a attributed string - */ - internal var simpleText: PDFSimpleText? + /// Instance of simple text object, will be converted into a attributed string + var simpleText: PDFSimpleText? - /** - Attributed string which will be drawn - */ - internal var attributedString: NSAttributedString! + /// Attributed string which will be drawn + var attributedString: NSAttributedString! /** - - If the given parameter `text` is neither a - instance of `PDFAttributedText` nor a `PDFSimpleText` a `fatalError()` will be thrown, - as there are no more subclasses of `PDFText` in the TPPDF framework. - - - parameter text: Subclass of `PDFText` + * Creates an instance wrapping the given `text`. + * + * - Parameter text: Subclass of `PDFText` + * + * - Precondition: `text` must be ``PDFSimpleText`` or ``PDFAttributedText``, otherwise a fatal exception is thrown */ - internal convenience init(text: T) { + convenience init(text: T) { if let attributedText = text as? PDFAttributedText { self.init(attributedText: attributedText) } else if let simpleText = text as? PDFSimpleText { self.init(simpleText: simpleText) } else { - fatalError() + fatalError("PDFText subtype \(T.self) is not supported") } } /** - Initialize with attributed text. - - - parameter attributedText: Object holding instance of `NSAttributedString` + * Initialize with attributed text. + * + * - Parameter attributedText: Object holding instance of `NSAttributedString` */ - internal init(attributedText: PDFAttributedText) { + init(attributedText: PDFAttributedText) { self.attributedText = attributedText } /** - Initialize with simple text object. - Will be converted into a attributed string using the default values from the generator. - - - parameter simpleText: Simple text object + * Initialize with simple text object. + * Will be converted into a attributed string using the default values from the generator. + * + * - Parameter simpleText: Simple text object */ - internal init(simpleText: PDFSimpleText) { + init(simpleText: PDFSimpleText) { self.simpleText = simpleText } /** - Calculates the frame and the text which will be drawn. - Also returns one or multiple page breaks and text objects, if text does not fit on one page. - - - parameter generator: Unused - - parameter container: Unused - - - throws: None + * Calculates the frame and the text which will be drawn. + * Also returns one or multiple page breaks and text objects, if text does not fit on one page. */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { var result: [PDFLocatedRenderObject] = [] // Generate attributed string if simple text, otherwise uses given attributedText @@ -85,9 +74,11 @@ internal class PDFAttributedTextObject: PDFRenderObject { // Calculate the text frame and the text which is on this page // If it is not possible to draw the whole text on this page, a remainder text is returned - let (frame, renderString, remainder) = PDFCalculations.calculateText(generator: generator, - container: container, - text: attributedString) + let (frame, renderString, remainder) = PDFCalculations.calculateText( + generator: generator, + container: container, + text: attributedString + ) // Set data to self, and add it to results attributedString = renderString @@ -115,12 +106,12 @@ internal class PDFAttributedTextObject: PDFRenderObject { /** Draws the text in the calculated frame using the Core Text framework. - - parameter generator: Unused - - parameter container: Unused + - Parameter generator: Unused + - Parameter container: Unused - - throws: None + - Throws: None */ - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator: PDFGenerator, container _: PDFContainer, in context: PDFContext) throws { if attributedString == nil { throw PDFError.textObjectNotCalculated } @@ -157,13 +148,13 @@ internal class PDFAttributedTextObject: PDFRenderObject { // If debugging is enabled, draw a outline around the text if generator.debug { - PDFGraphics.drawRect(in: context, rect: self.frame, + PDFGraphics.drawRect(in: context, rect: frame, outline: .init(type: .dashed, color: .red, width: 1.0), fill: .clear) } let allRange = NSRange(location: 0, length: attributedString.length) var links: [(String, NSRange)] = [] - attributedString.enumerateAttribute(.link, in: allRange) { (obj, range, _) in + attributedString.enumerateAttribute(.link, in: allRange) { obj, range, _ in if let url = obj as? String { links.append((url, range)) } @@ -175,7 +166,7 @@ internal class PDFAttributedTextObject: PDFRenderObject { private func calculateLinkAttributes(with links: [(url: String, range: NSRange)], in frameRef: CTFrame, - in allRange: NSRange, + in _: NSRange, context: PDFContext, debug: Bool) { guard let lines = CTFrameGetLines(frameRef) as? [CTLine] else { @@ -191,18 +182,18 @@ internal class PDFAttributedTextObject: PDFRenderObject { var lineOrigin = CGPoint.zero CTFrameGetLineOrigins(frameRef, CFRange(location: lines.count - i - 1, length: 1), &lineOrigin) - let lineBounds = CGRect(x: self.frame.origin.x, - y: self.frame.origin.y + lineOrigin.y, + let lineBounds = CGRect(x: frame.origin.x, + y: frame.origin.y + lineOrigin.y, width: typoBounds, height: ascent + descent + leading) lineMetrics.append((line: line, bounds: lineBounds, range: CTLineGetStringRange(line))) } - + for link in links { guard let url = URL(string: link.url) else { continue } - + var found = false for metric in lineMetrics { guard let intersection = NSRange(location: metric.range.location, length: metric.range.length).intersection(link.range) else { @@ -212,17 +203,18 @@ internal class PDFAttributedTextObject: PDFRenderObject { continue } } - + found = true - + let startOffset = CTLineGetOffsetForStringIndex(metric.line, intersection.location, nil) let endOffset = CTLineGetOffsetForStringIndex(metric.line, intersection.location + intersection.length, nil) let linkFrame = CGRect( - x: self.frame.origin.x + startOffset, + x: frame.origin.x + startOffset, y: metric.bounds.origin.y, width: endOffset - startOffset, - height: metric.bounds.height) + height: metric.bounds.height + ) attributes.append((attribute: .link(url: url), frame: linkFrame)) if debug { @@ -240,25 +232,26 @@ internal class PDFAttributedTextObject: PDFRenderObject { If a simple text object is given, it will generate default string attributes. If a attributed text is given, it will return the attributed string instance - - parameter generator: Generator, which holds font and text color data - - parameter container: Container, where this text object is drawn + - Parameter generator: Generator, which holds font and text color data + - Parameter container: Container, where this text object is drawn - - throws: PDFError.textObjectIsNil, if neither `simpleText` nor `attributedText` is set + - Throws: PDFError.textObjectIsNil, if neither `simpleText` nor `attributedText` is set - - returns: `NSAttributedString`, either created from `PDFAttributedTextObject.simpleText` or + - Returns: `NSAttributedString`, either created from `PDFAttributedTextObject.simpleText` or from extracted from `PDFAttributedTextObject.attributedText` */ - internal func generateAttributedText(generator: PDFGenerator, container: PDFContainer) throws -> NSAttributedString { - if let simple = self.simpleText { + func generateAttributedText(generator: PDFGenerator, container: PDFContainer) throws -> NSAttributedString { + if let simple = simpleText { let attributes = PDFAttributedTextObject.generateDefaultTextAttributes( container: container, fonts: &generator.fonts, textColor: &generator.textColor, spacing: simple.spacing, - style: simple.style) + style: simple.style + ) return NSAttributedString(string: simple.text, attributes: attributes) - } else if let attributedText = self.attributedText { + } else if let attributedText = attributedText { return attributedText.text } else { throw PDFError.textObjectIsNil @@ -268,19 +261,19 @@ internal class PDFAttributedTextObject: PDFRenderObject { /** Creates the default text attributes, depending on the given `container` - - parameter container: Container - - parameter fonts: Reference to fonts per container - - parameter textColor: Reference to text color per continaer - - parameter spacing: Line spacing - - parameter style: Optional style used to overrule generator settings + - Parameter container: Container + - Parameter fonts: Reference to fonts per container + - Parameter textColor: Reference to text color per continaer + - Parameter spacing: Line spacing + - Parameter style: Optional style used to overrule generator settings - - returns: Attributes dictionary, used for `NSAttributedString` creation + - Returns: Attributes dictionary, used for `NSAttributedString` creation */ - internal static func generateDefaultTextAttributes(container: PDFContainer, - fonts: inout [PDFContainer: Font], - textColor: inout [PDFContainer: Color], - spacing: CGFloat, - style: PDFTextStyle?) -> [NSAttributedString.Key: NSObject] { + static func generateDefaultTextAttributes(container: PDFContainer, + fonts: inout [PDFContainer: Font], + textColor: inout [PDFContainer: Color], + spacing: CGFloat, + style: PDFTextStyle?) -> [NSAttributedString.Key: NSObject] { let paragraphStyle = NSMutableParagraphStyle() if container.isLeft { paragraphStyle.alignment = .left @@ -298,10 +291,8 @@ internal class PDFAttributedTextObject: PDFRenderObject { ] } - /** - TODO: Documentation - */ - override internal var copy: PDFRenderObject { - PDFAttributedTextObject(text: (self.attributedText ?? self.simpleText)!) + /// nodoc + override var copy: PDFRenderObject { + PDFAttributedTextObject(text: (attributedText ?? simpleText)!) } } diff --git a/Source/Internal/Text/PDFFontObject.swift b/Source/Internal/Text/PDFFontObject.swift index fc53fbde..845d1858 100644 --- a/Source/Internal/Text/PDFFontObject.swift +++ b/Source/Internal/Text/PDFFontObject.swift @@ -6,41 +6,40 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Changes the font of the container, where this object is in. */ -internal class PDFFontObject: PDFRenderObject { - +class PDFFontObject: PDFRenderObject { /** New font of container after calculation */ - internal var font: Font + var font: Font /** Initializer - - parameter font: New font + - Parameter font: New font */ - internal init(font: Font) { + init(font: Font) { self.font = font } /** Sets the font in `container` - - parameter generator: Generator which holds font information - - parameter container: Container, where the font is changed + - Parameter generator: Generator which holds font information + - Parameter container: Container, where the font is changed - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { generator.fonts[container] = font return [(container, self)] @@ -49,7 +48,7 @@ internal class PDFFontObject: PDFRenderObject { /** Creates a new `PDFFontObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFFontObject(font: self.font) + override var copy: PDFRenderObject { + PDFFontObject(font: font) } } diff --git a/Source/Internal/Text/PDFTextColorObject.swift b/Source/Internal/Text/PDFTextColorObject.swift index b12df76f..b5012d30 100644 --- a/Source/Internal/Text/PDFTextColorObject.swift +++ b/Source/Internal/Text/PDFTextColorObject.swift @@ -6,41 +6,40 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif /** Changes the text color in the container, where this object is in. */ -internal class PDFTextColorObject: PDFRenderObject { - +class PDFTextColorObject: PDFRenderObject { /** New text color in container after calculation */ - internal var color: Color + var color: Color /** Initializer - - parameter textColor: New text color + - Parameter textColor: New text color */ - internal init(color: Color) { + init(color: Color) { self.color = color } /** Sets the text color in `container` - - parameter generator: Generator which holds font information - - parameter container: Container, where the font is changed + - Parameter generator: Generator which holds font information + - Parameter container: Container, where the font is changed - - throws: None + - Throws: None - - returns: Self + - Returns: Self */ - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { generator.textColor[container] = color return [(container, self)] @@ -49,7 +48,7 @@ internal class PDFTextColorObject: PDFRenderObject { /** Creates a new `PDFTextColorObject` with the same properties */ - override internal var copy: PDFRenderObject { - PDFTextColorObject(color: self.color) + override var copy: PDFRenderObject { + PDFTextColorObject(color: color) } } diff --git a/Source/Internal/Utils/Attributes/PDFAttributableObject.swift b/Source/Internal/Utils/Attributes/PDFAttributableObject.swift index 4746e2da..8f77ac1a 100644 --- a/Source/Internal/Utils/Attributes/PDFAttributableObject.swift +++ b/Source/Internal/Utils/Attributes/PDFAttributableObject.swift @@ -9,17 +9,15 @@ Protocol for adding attributes to an object */ public protocol PDFAttributableObject { - /** - - returns: List off attributes of this object + - Returns: List off attributes of this object */ var attributes: [PDFObjectAttribute] { get } /** Adds an attribute to the list of this object - - parameter attribute: Attribute used for further calculations + - Parameter attribute: Attribute used for further calculations */ func add(attribute: PDFObjectAttribute) - } diff --git a/Source/Internal/Utils/Attributes/PDFObjectAttribute.swift b/Source/Internal/Utils/Attributes/PDFObjectAttribute.swift index 73bdb913..d8400f49 100644 --- a/Source/Internal/Utils/Attributes/PDFObjectAttribute.swift +++ b/Source/Internal/Utils/Attributes/PDFObjectAttribute.swift @@ -11,10 +11,8 @@ import Foundation List of attributes an object can obtain */ public enum PDFObjectAttribute: Hashable { - /** Adds a clickable link with a redirection to the given URL */ case link(url: URL) - } diff --git a/Source/Internal/Utils/CustomStringConvertible+AutoDescribing.swift b/Source/Internal/Utils/CustomStringConvertible+AutoDescribing.swift index ff17f30f..621ad208 100644 --- a/Source/Internal/Utils/CustomStringConvertible+AutoDescribing.swift +++ b/Source/Internal/Utils/CustomStringConvertible+AutoDescribing.swift @@ -7,15 +7,14 @@ import Foundation -extension CustomStringConvertible { - +public extension CustomStringConvertible { /** Default implementation for `description` using class reflection to create a comma concatenated list of properties and values - Returns: String of comma-separated key/value pairs */ - public var description: String { - var description: String = "" + var description: String { + var description = "" description = withUnsafePointer(to: self) { pointer in String(format: "%@<%p>", String(describing: type(of: self)), pointer) } @@ -23,25 +22,24 @@ extension CustomStringConvertible { return String(format: "%@(%@)", description, selfMirror.children - .compactMap({ child in - if let propertyName = child.label { - return "\(propertyName): \(child.value)" - } - return nil - }) - .joined(separator: ", ")) + .compactMap { child in + if let propertyName = child.label { + return "\(propertyName): \(child.value)" + } + return nil + } + .joined(separator: ", ")) } } -extension CustomDebugStringConvertible { - +public extension CustomDebugStringConvertible { /** Default implementation for `debugDescription` using class reflection to create a comma concatenated list of properties and values - Returns: String of comma-separated key/value pairs */ - public var debugDescription: String { - var description: String = "" + var debugDescription: String { + var description = "" description = String(format: "%@<%@>", String(describing: type(of: self)), Unmanaged.passUnretained(self as AnyObject).toOpaque().debugDescription) @@ -49,12 +47,12 @@ extension CustomDebugStringConvertible { return String(format: "%@(%@)", description, selfMirror.children - .compactMap({ child in - if let propertyName = child.label { - return "\(propertyName): \(child.value)" - } - return nil - }) - .joined(separator: ", ")) + .compactMap { child in + if let propertyName = child.label { + return "\(propertyName): \(child.value)" + } + return nil + } + .joined(separator: ", ")) } } diff --git a/Source/Internal/Utils/FileManager+TemporaryFiles.swift b/Source/Internal/Utils/FileManager+TemporaryFiles.swift index 855e28e0..8c5ae688 100644 --- a/Source/Internal/Utils/FileManager+TemporaryFiles.swift +++ b/Source/Internal/Utils/FileManager+TemporaryFiles.swift @@ -8,7 +8,6 @@ import Foundation extension FileManager { - /** Creates a guaranteed temporary PDF file URL with the given name @@ -16,7 +15,7 @@ extension FileManager { - Returns: URL to a temporary file */ - internal static func generateTemporaryOutputURL(for name: String) -> URL { + static func generateTemporaryOutputURL(for name: String) -> URL { let normalisedName = name.lowercased().hasSuffix(".pdf") ? name : (name + ".pdf") return URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(normalisedName) } diff --git a/Source/Internal/Utils/PDFCalculations.swift b/Source/Internal/Utils/PDFCalculations.swift index 6f4b4828..70dfdebb 100644 --- a/Source/Internal/Utils/PDFCalculations.swift +++ b/Source/Internal/Utils/PDFCalculations.swift @@ -6,32 +6,29 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif -// swiftlint:disable function_body_length - -/** - A collection of static calculations utilities - */ -internal enum PDFCalculations { +// swiftlint:disable function_body_length file_length type_body_length +/// A collection of static calculations utilities +enum PDFCalculations { // MARK: - INTERNAL STATIC FUNCS /** Calculates the frame, the string that fits in the given `container` and the remainding string. - - parameter generator: Generator which is calculating - - parameter container: Container where text is drawn - - parameter text: Text which should be calculated and drawn + - Parameter generator: Generator which is calculating + - Parameter container: Container where text is drawn + - Parameter text: Text which should be calculated and drawn - - returns: Tuple of text `frame`, text which fits in frame and the remainding text which did not fit + - Returns: Tuple of text `frame`, text which fits in frame and the remainding text which did not fit */ - internal static func calculateText(generator: PDFGenerator, - container: PDFContainer, - text: NSAttributedString) -> (frame: CGRect, render: NSAttributedString?, remainder: NSAttributedString?) { + static func calculateText(generator: PDFGenerator, + container: PDFContainer, + text: NSAttributedString) -> (frame: CGRect, render: NSAttributedString?, remainder: NSAttributedString?) { let availableSize = calculateAvailableFrame(for: generator, in: container) guard availableSize.height > 0 else { return (frame: .zero, render: nil, remainder: text) @@ -46,22 +43,22 @@ internal enum PDFCalculations { ) } - internal struct TextCalculationResult { - internal var text: NSAttributedString - internal var size: CGSize - internal var remainder: NSAttributedString? + struct TextCalculationResult { + var text: NSAttributedString + var size: CGSize + var remainder: NSAttributedString? } /** Calculates the actual size of the text and the remainder which does not fit the given `bounds` - - parameter text: Text which is calculated - - parameter bounds: Bounds where text should fit + - Parameter text: Text which is calculated + - Parameter bounds: Bounds where text should fit - - returns: Tuple of `text`, real `size of the text and the `remainder` + - Returns: Tuple of `text`, real `size of the text and the `remainder` */ - internal static func calculateTextSizeAndRemainder(of text: NSAttributedString, - in bounds: CGSize) -> TextCalculationResult { + static func calculateTextSizeAndRemainder(of text: NSAttributedString, + in bounds: CGSize) -> TextCalculationResult { assert(bounds.width > 0 && bounds.height > 0, "Can't render text if no space available") let framesetter = CTFramesetterCreateWithAttributedString(text) @@ -92,12 +89,12 @@ internal enum PDFCalculations { /** Calculates the available bounds size in a given `container` - - parameter generator: Generator doing the calculations - - parameter container: Container which size is calculated + - Parameter generator: Generator doing the calculations + - Parameter container: Container which size is calculated - - returns: Available bounds size in points + - Returns: Available bounds size in points */ - internal static func calculateAvailableFrame(for generator: PDFGenerator, in container: PDFContainer) -> CGSize { + static func calculateAvailableFrame(for generator: PDFGenerator, in container: PDFContainer) -> CGSize { CGSize( width: calculateAvailableFrameWidth(for: generator, in: container), height: calculateAvailableFrameHeight(for: generator, in: container) @@ -107,12 +104,12 @@ internal enum PDFCalculations { /** Calculates the available width in a given `container` - - parameter generator: Generator used for calculations - - parameter container: Container in question + - Parameter generator: Generator used for calculations + - Parameter container: Container in question - - returns: Available width in points + - Returns: Available width in points */ - internal static func calculateAvailableFrameWidth(for generator: PDFGenerator, in container: PDFContainer) -> CGFloat { + static func calculateAvailableFrameWidth(for generator: PDFGenerator, in container: PDFContainer) -> CGFloat { let columnInset = generator.columnState.getInset(for: container) return generator.document.layout.width - generator.layout.margin.left @@ -149,10 +146,10 @@ internal enum PDFCalculations { /// ┃ bottom margin ┃ /// ┗━━━━━━━━━━━━━━━━┛ /// - /// - parameter generator: Generator used for calculations - /// - parameter container: Container in question - /// - returns: Available height in points - internal static func calculateAvailableFrameHeight(for generator: PDFGenerator, in container: PDFContainer) -> CGFloat { + /// - Parameter generator: Generator used for calculations + /// - Parameter container: Container in question + /// - Returns: Available height in points + static func calculateAvailableFrameHeight(for generator: PDFGenerator, in container: PDFContainer) -> CGFloat { let pageLayout = generator.document.layout if container.isHeader || container.isFooter { @@ -186,7 +183,7 @@ internal enum PDFCalculations { /// /// - Parameter generator: Generator currently in use holding information about the document /// - Returns: Offset from top edge in points - internal static func calculateTopMinimum(for generator: PDFGenerator) -> CGFloat { + static func calculateTopMinimum(for generator: PDFGenerator) -> CGFloat { let layout = generator.layout let pageLayout = generator.document.layout let headerHeight = layout.heights.maxHeaderHeight() @@ -223,7 +220,7 @@ internal enum PDFCalculations { /// /// - Parameter generator: Generator currently in use holding information about the document /// - Returns: Offset from top edge in points - internal static func calculateBottomMaximum(for generator: PDFGenerator) -> CGFloat { + static func calculateBottomMaximum(for generator: PDFGenerator) -> CGFloat { let layout = generator.layout let pageLayout = generator.document.layout let footerHeight = layout.heights.maxFooterHeight() @@ -238,13 +235,13 @@ internal enum PDFCalculations { /** Calculates the position of an element with given `size` in the given `container - - parameter generator: Generator doing the calculations - - parameter container: Container where element is in - - parameter size: Size of element + - Parameter generator: Generator doing the calculations + - Parameter container: Container where element is in + - Parameter size: Size of element - - returns: Position of element + - Returns: Position of element */ - internal static func calculateElementPosition(for generator: PDFGenerator, in container: PDFContainer, with size: CGSize) -> CGPoint { + static func calculateElementPosition(for generator: PDFGenerator, in container: PDFContainer, with size: CGSize) -> CGPoint { CGPoint( x: calculatePositionX(for: generator, in: container, with: size), y: calculatePositionY(for: generator, in: container, with: size) @@ -252,9 +249,7 @@ internal enum PDFCalculations { } // MARK: - PRIVATE STATIC FUNCS - /** - TODO: Documentation - */ + private static func calculatePositionX(for generator: PDFGenerator, in container: PDFContainer, with size: CGSize) -> CGFloat { let layout = generator.layout let columnInset = generator.columnState.getInset(for: container) @@ -310,10 +305,8 @@ internal enum PDFCalculations { /// ┃│ Next Element │┃ /// ┃└──────────────────┘┃ /// - /// - Parameter generator: Generator currently in use holding information about the document - /// - Returns: Offset from top edge in points /// - Parameters: - /// - generator: Active generator + /// - generator: Generator currently in use holding information about the document /// - container: Container where element is placed /// - size: Size of element /// - Returns: Offset from the top edge @@ -334,10 +327,7 @@ internal enum PDFCalculations { } } - /** - TODO: Documentation - */ - internal static func calculateContentOffset(for generator: PDFGenerator, of element: PDFRenderObject, in container: PDFContainer) -> CGFloat { + static func calculateContentOffset(for generator: PDFGenerator, of element: PDFRenderObject, in container: PDFContainer) -> CGFloat { let layout = generator.layout let pageLayout = generator.document.layout @@ -354,10 +344,7 @@ internal enum PDFCalculations { return element.frame.minY - calculateTopMinimum(for: generator) } - /** - TODO: Documentation - */ - internal static func calculateContentOffset(for generator: PDFGenerator, of offset: CGFloat, in container: PDFContainer) -> CGFloat { + static func calculateContentOffset(for generator: PDFGenerator, of offset: CGFloat, in container: PDFContainer) -> CGFloat { let layout = generator.layout let pageLayout = generator.document.layout @@ -375,16 +362,15 @@ internal enum PDFCalculations { // MARK: - LEGACY - /** - TODO: Documentation - */ - internal static func calculateCellFrame(generator: PDFGenerator, - container: PDFContainer, - position: (origin: CGPoint, width: CGFloat), - text: NSAttributedString, - alignment: PDFTableCellAlignment) -> CGRect { + static func calculateCellFrame( + generator _: PDFGenerator, + container _: PDFContainer, + position: (origin: CGPoint, width: CGFloat), + text: NSAttributedString, + alignment: PDFTableCellAlignment + ) -> CGRect { let textMaxHeight = CGFloat.greatestFiniteMagnitude // PDFCalculations.calculateAvailableFrameHeight(for: generator, in: container) - let frame: CGRect = CGRect(x: position.origin.x, y: position.origin.y, width: position.width, height: textMaxHeight) + let frame = CGRect(x: position.origin.x, y: position.origin.y, width: position.width, height: textMaxHeight) let currentRange = CFRange(location: 0, length: 0) let (_, _, drawnSize) = calculateTextFrameAndDrawnSizeInOnePage(frame: frame, text: text, currentRange: currentRange) @@ -401,10 +387,7 @@ internal enum PDFCalculations { return CGRect(origin: CGPoint(x: x, y: position.origin.y), size: CGSize(width: drawnSize.width, height: drawnSize.height)) } - /** - TODO: Documentation - */ - internal static func calculateCellFrame(generator: PDFGenerator, origin: CGPoint, width: CGFloat, image: Image) -> CGRect { + static func calculateCellFrame(generator _: PDFGenerator, origin: CGPoint, width: CGFloat, image: Image) -> CGRect { let imageSize = image.size var imageHeight = 0.0 var imageWidth = 0.0 @@ -422,14 +405,13 @@ internal enum PDFCalculations { return CGRect(x: origin.x, y: origin.y, width: imageWidth, height: imageHeight) } - /** - TODO: Documentation - */ - internal static func calculateTextFrameAndDrawnSizeInOnePage(generator: PDFGenerator, - container: PDFContainer, - text: CFAttributedString, - currentRange: CFRange, - textMaxWidth: CGFloat) -> (CGRect, CTFrame, CGSize) { + static func calculateTextFrameAndDrawnSizeInOnePage( + generator: PDFGenerator, + container: PDFContainer, + text: CFAttributedString, + currentRange: CFRange, + textMaxWidth: CGFloat + ) -> (CGRect, CTFrame, CGSize) { let textMaxWidth = (textMaxWidth > 0) ? textMaxWidth : (generator.document.layout.width - generator.layout.margin.left - generator.layout.margin.right @@ -472,23 +454,29 @@ internal enum PDFCalculations { let frame: CGRect = { if container.isHeader { - return CGRect(x: x, - y: 0, - width: textMaxWidth, - height: textMaxHeight) + return CGRect( + x: x, + y: 0, + width: textMaxWidth, + height: textMaxHeight + ) } else if container.isFooter { - return CGRect(x: x, - y: generator.document.layout.height - - generator.layout.heights.footer[container]!, - width: textMaxWidth, - height: textMaxHeight) + return CGRect( + x: x, + y: generator.document.layout.height + - generator.layout.heights.footer[container]!, + width: textMaxWidth, + height: textMaxHeight + ) } else { - return CGRect(x: x, - y: generator.layout.heights.content - + generator.layout.heights.maxHeaderHeight() - + generator.document.layout.space.header, - width: textMaxWidth, - height: textMaxHeight) + return CGRect( + x: x, + y: generator.layout.heights.content + + generator.layout.heights.maxHeaderHeight() + + generator.document.layout.space.header, + width: textMaxWidth, + height: textMaxHeight + ) } }() @@ -500,15 +488,17 @@ internal enum PDFCalculations { First it uses`CoreText` to create a `CTFramesetter`, then calculates the visible range in the given `frame` and returns the range of text, actually fitting the frame. - - parameter frame: Rectangle used as limitation bounds of text - - parameter text: Attributed string that will be rendered - - parameter currentRange: Character offset, used to select substring + - Parameter frame: Rectangle used as limitation bounds of text + - Parameter text: Attributed string that will be rendered + - Parameter currentRange: Character offset, used to select substring - - returns: Tuple holding the given frame, the calculated framesetter reference and the draw size + - Returns: Tuple holding the given frame, the calculated framesetter reference and the draw size */ - internal static func calculateTextFrameAndDrawnSizeInOnePage(frame: CGRect, - text: CFAttributedString, - currentRange: CFRange) -> (CGRect, CTFrame, CGSize) { + static func calculateTextFrameAndDrawnSizeInOnePage( + frame: CGRect, + text: CFAttributedString, + currentRange: CFRange + ) -> (CGRect, CTFrame, CGSize) { let framesetter = CTFramesetterCreateWithAttributedString(text) let framePath = BezierPath(rect: frame).cgPath @@ -526,22 +516,21 @@ internal enum PDFCalculations { return (frame, frameRef, drawnSize) } - /** - TODO: Documentation - */ - internal static func calculateImageCaptionSize(generator: PDFGenerator, - container: PDFContainer, - image: PDFImage, - size: CGSize, - sizeFit: PDFImageSizeFit) -> (CGSize, CGSize) { + static func calculateImageCaptionSize( + generator: PDFGenerator, + container: PDFContainer, + image: PDFImage, + size: CGSize, + sizeFit: PDFImageSizeFit + ) -> (CGSize, CGSize) { /* calculate the aspect size of image */ let size = (size == CGSize.zero) ? image.size : size /* calculate caption height if a caption exists */ let captionHeight: CGFloat = - (image.caption as? PDFAttributedText).map({ $0.text.size().height }) - ?? (image.caption as? PDFSimpleText).map({ $0.text.size().height }) - ?? 0 + (image.caption as? PDFAttributedText).map { $0.text.size().height } + ?? (image.caption as? PDFSimpleText).map { $0.text.size().height } + ?? 0 let maxWidth = min(size.width, calculateAvailableFrameWidth(for: generator, in: container)) let maxHeight = min(size.height, calculateAvailableFrameHeight(for: generator, in: container) - captionHeight) @@ -565,10 +554,7 @@ internal enum PDFCalculations { return (imageSize, CGSize(width: imageSize.width, height: captionHeight)) } - /** - TODO: Documentation - */ - internal static func calculateColumnWrapInset(generator: PDFGenerator, container: PDFContainer) -> (left: CGFloat, right: CGFloat) { + static func calculateColumnWrapInset(generator: PDFGenerator, container: PDFContainer) -> (left: CGFloat, right: CGFloat) { guard let maxColumn = generator.columnState.getMaxColumns(for: container) else { return (0, 0) } @@ -590,10 +576,7 @@ internal enum PDFCalculations { return (left: left, right: right) } - /** - TODO: Documentation - */ - internal static func calculateColumnWrapSpacing(generator: PDFGenerator, container: PDFContainer) -> (left: CGFloat, right: CGFloat) { + static func calculateColumnWrapSpacing(generator: PDFGenerator, container: PDFContainer) -> (left: CGFloat, right: CGFloat) { guard let maxColumn = generator.columnState.getMaxColumns(for: container) else { return (0, 0) } @@ -615,3 +598,5 @@ internal enum PDFCalculations { return (left: left, right: right) } } + +// swiftlint:enable function_body_length file_length type_body_length diff --git a/Source/Internal/Utils/PDFLocatedRenderObject.swift b/Source/Internal/Utils/PDFLocatedRenderObject.swift index c022dab4..9f959180 100644 --- a/Source/Internal/Utils/PDFLocatedRenderObject.swift +++ b/Source/Internal/Utils/PDFLocatedRenderObject.swift @@ -5,9 +5,5 @@ // Created by Philip Niedertscheider on 22.12.19. // -import Foundation - -/** - Holds a `PDFRenderObject` and the `PDFContainer` it is located in - */ +/// Structure to extend ``PDFRenderObject`` with the ``PDFContainer`` it is located in public typealias PDFLocatedRenderObject = (PDFContainer, PDFRenderObject) diff --git a/Source/Internal/Utils/PDFSlicedObject.swift b/Source/Internal/Utils/PDFSlicedObject.swift index b5fb5819..4cf0c0c4 100644 --- a/Source/Internal/Utils/PDFSlicedObject.swift +++ b/Source/Internal/Utils/PDFSlicedObject.swift @@ -6,29 +6,28 @@ // #if os(iOS) -import UIKit + import UIKit #elseif os(macOS) -import AppKit + import AppKit #endif import CoreGraphics -internal class PDFSlicedObject: PDFRenderObject { +class PDFSlicedObject: PDFRenderObject { + var children: [PDFRenderObject] - internal var children: [PDFRenderObject] - - internal init(children: [PDFRenderObject] = [], frame: CGRect = .null) { + init(children: [PDFRenderObject] = [], frame: CGRect = .null) { self.children = children super.init() self.frame = frame } - override internal func calculate(generator: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { + override func calculate(generator _: PDFGenerator, container: PDFContainer) throws -> [PDFLocatedRenderObject] { [ (container, self) ] } - override internal func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { if frame != .null { context.saveGState() context.beginPath() diff --git a/Source/Internal/Utils/Stack.swift b/Source/Internal/Utils/Stack.swift index 7ad8af9f..1f4be148 100644 --- a/Source/Internal/Utils/Stack.swift +++ b/Source/Internal/Utils/Stack.swift @@ -11,7 +11,6 @@ import Foundation Data Structure used to manage a collection of elements after the LIFO (last in, first out) principle. */ public struct Stack { - /** Data structure used to manage elements */ @@ -25,14 +24,14 @@ public struct Stack { } /** - - returns: `true` if element count is zero, `false` otherwise + - Returns: `true` if element count is zero, `false` otherwise */ public var isEmpty: Bool { array.isEmpty } /** - - returns: Number of elements in stack + - Returns: Number of elements in stack */ public var count: Int { array.count @@ -41,9 +40,9 @@ public struct Stack { /** Adds an element on top of the stack - - parameter element: Element to be pushed on top of stack + - Parameter element: Element to be pushed on top of stack - - returns: Instance of stack for chaining + - Returns: Instance of stack for chaining */ @discardableResult public mutating func push(_ element: T) -> Stack { @@ -55,9 +54,9 @@ public struct Stack { Removes the last element or if a `count` is given as many until the stack is empty. Afterwards it returns the last removed element. - - parameter count: Amount of elements to remove, can be nil + - Parameter count: Amount of elements to remove, can be nil - - returns: Last element which was removed, or nil if stack is empty + - Returns: Last element which was removed, or nil if stack is empty */ @discardableResult public mutating func pop(to count: Int? = nil) -> T? { @@ -74,12 +73,12 @@ public struct Stack { /** Returns the element at the given index without changing the stack - - parameter index: from bottom up + - Parameter index: from bottom up - - returns: element at `index` or nil if out of bounds + - Returns: element at `index` or nil if out of bounds */ public func peek(at index: Int) -> T? { - guard index >= 0 && index < count else { + guard index >= 0, index < count else { return nil } return array[index] @@ -88,7 +87,7 @@ public struct Stack { /** Returns the last inserted element - - returns: Element` or nil if empty + - Returns: Element` or nil if empty */ public var top: T? { array.last @@ -97,9 +96,9 @@ public struct Stack { /** Returns the element from the reverse order - - parameter index: distance to most top element + - Parameter index: distance to most top element - - returns: element at `index` or nil if out of bounds + - Returns: element at `index` or nil if out of bounds */ public func fromTop(index: Int) -> T? { let i = array.count - 1 - index @@ -107,8 +106,9 @@ public struct Stack { } } -extension Stack: CustomStringConvertible where T: CustomStringConvertible { +// MARK: CustomStringConvertible +extension Stack: CustomStringConvertible where T: CustomStringConvertible { public var description: String { withUnsafePointer(to: self) { pointer in String(format: "Stack<%p> { %@ }", pointer, array.map(\.description).joined(separator: "\n")) @@ -116,8 +116,9 @@ extension Stack: CustomStringConvertible where T: CustomStringConvertible { } } -extension Stack: CustomDebugStringConvertible where T: CustomDebugStringConvertible { +// MARK: CustomDebugStringConvertible +extension Stack: CustomDebugStringConvertible where T: CustomDebugStringConvertible { public var debugDescription: String { withUnsafePointer(to: self) { pointer in String(format: "Stack<%p> { %@ }", pointer, array.map(\.debugDescription).joined(separator: "\n")) diff --git a/Source/Internal/Utils/WeakRef.swift b/Source/Internal/Utils/WeakRef.swift index 66d6b0ed..f5b31e38 100644 --- a/Source/Internal/Utils/WeakRef.swift +++ b/Source/Internal/Utils/WeakRef.swift @@ -10,19 +10,18 @@ import Foundation /** Utility class used for weak reference wrapping */ -internal class WeakRef where T: AnyObject { - +class WeakRef where T: AnyObject { /** Holds a weak reference to an instance */ - internal private(set) weak var value: T? + private(set) weak var value: T? /** Creates a new weak reference instance, holding a reference to the given value - - parameter value: Value to be weakly referenced + - Parameter value: Value to be weakly referenced */ - internal init(value: T?) { + init(value: T?) { self.value = value } } diff --git a/Tests/Common/Bundle+Module.swift b/Tests/Common/Bundle+Module.swift index 4c870e4b..f571d4f9 100644 --- a/Tests/Common/Bundle+Module.swift +++ b/Tests/Common/Bundle+Module.swift @@ -1,17 +1,16 @@ import Foundation extension Bundle { - private static var productsDirectory: URL { #if os(macOS) - if let bundle = Bundle.allBundles.first(where: { $0.bundlePath.hasSuffix(".xctest") }) { - return bundle.bundleURL.deletingLastPathComponent() - } - fatalError("Couldn't find the products directory") + if let bundle = Bundle.allBundles.first(where: { $0.bundlePath.hasSuffix(".xctest") }) { + return bundle.bundleURL.deletingLastPathComponent() + } + fatalError("Couldn't find the products directory") #else - return Bundle.main.bundleURL + return Bundle.main.bundleURL #endif } - static var module: Bundle = Bundle.main + static var module: Bundle = .main } diff --git a/Tests/TPPDFIntegrationTests/EmptyDocumentTests.swift b/Tests/TPPDFIntegrationTests/EmptyDocumentTests.swift index 0bd2cb09..09efc65d 100644 --- a/Tests/TPPDFIntegrationTests/EmptyDocumentTests.swift +++ b/Tests/TPPDFIntegrationTests/EmptyDocumentTests.swift @@ -1,12 +1,11 @@ import Foundation -import Quick import Nimble -@testable import TPPDF import PDFKit +import Quick +@testable import TPPDF @available(iOS 11.0, *) class EmptyDocumentTests: QuickSpec { - override func spec() { describe("Empty Document") { it("it should have a single page") { diff --git a/Tests/TPPDFIntegrationTests/ExternalDocumentTests.swift b/Tests/TPPDFIntegrationTests/ExternalDocumentTests.swift index 3a9d6afb..78429795 100644 --- a/Tests/TPPDFIntegrationTests/ExternalDocumentTests.swift +++ b/Tests/TPPDFIntegrationTests/ExternalDocumentTests.swift @@ -1,17 +1,15 @@ import Foundation -import Quick import Nimble -@testable import TPPDF import PDFKit +import Quick +@testable import TPPDF @available(iOS 11.0, *) class ExternalDocumentTests: QuickSpec { - override func spec() { describe("External Document") { context("only document") { context("debug mode") { - // Test Case: // Precondition: // - Document is empty @@ -42,7 +40,6 @@ class ExternalDocumentTests: QuickSpec { } context("normal mode") { - // Test Case: // Precondition: // - Document is empty @@ -75,7 +72,6 @@ class ExternalDocumentTests: QuickSpec { context("content before document") { context("debug mode") { - // Test Case: // Precondition: // - Document contains content @@ -107,7 +103,6 @@ class ExternalDocumentTests: QuickSpec { } context("normal mode") { - // Test Case: // Precondition: // - Document contains content @@ -141,7 +136,6 @@ class ExternalDocumentTests: QuickSpec { context("content after document") { context("debug mode") { - // Test Case: // Precondition: // - Document is empty before adding external document @@ -174,7 +168,6 @@ class ExternalDocumentTests: QuickSpec { } context("normal mode") { - // Test Case: // Precondition: // - Document is empty before adding external document @@ -209,7 +202,6 @@ class ExternalDocumentTests: QuickSpec { context("document between content") { context("debug mode") { - // Test Case: // Precondition: // - Document has content before external documnet @@ -244,7 +236,6 @@ class ExternalDocumentTests: QuickSpec { } context("normal mode") { - // Test Case: // Precondition: // - Document has content before external documnet @@ -281,7 +272,6 @@ class ExternalDocumentTests: QuickSpec { context("multiple external documents") { context("debug mode") { - // Test Case: // Precondition: // - Document contains 2 external documents @@ -343,7 +333,6 @@ class ExternalDocumentTests: QuickSpec { } context("normal mode") { - // Test Case: // Precondition: // - Document contains 5 external documents diff --git a/Tests/TPPDFTests/API/Table/Sections/PDFTableRowSpec.swift b/Tests/TPPDFTests/API/Table/Sections/PDFTableRowSpec.swift index 3e1512d0..0f65ae1b 100644 --- a/Tests/TPPDFTests/API/Table/Sections/PDFTableRowSpec.swift +++ b/Tests/TPPDFTests/API/Table/Sections/PDFTableRowSpec.swift @@ -5,12 +5,11 @@ // Created by Philip Niedertscheider on 23.09.20. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableRowSpec: QuickSpec { - override func spec() { describe("PDFTableRow") { describe("alignment") { @@ -20,11 +19,10 @@ class PDFTableRowSpec: QuickSpec { expect(table.rows.alignment) == [ [.left, .center, .right], [.left, .center, .right], - [.left, .center, .right] + [.left, .center, .right], ] } } } } } - diff --git a/Tests/TPPDFTests/API/Table/Sections/PDFTable_RowSubscriptsSpec.swift b/Tests/TPPDFTests/API/Table/Sections/PDFTable_RowSubscriptsSpec.swift index bfc760f4..5ae72acb 100644 --- a/Tests/TPPDFTests/API/Table/Sections/PDFTable_RowSubscriptsSpec.swift +++ b/Tests/TPPDFTests/API/Table/Sections/PDFTable_RowSubscriptsSpec.swift @@ -5,12 +5,11 @@ // Created by Philip Niedertscheider on 23.09.20. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTable_RowSubscriptsSpec: QuickSpec { - override func spec() { describe("PDFTable") { describe("Row Subscripts") { diff --git a/Tests/TPPDFTests/Graphics/PDFGraphics_Spec.swift b/Tests/TPPDFTests/Graphics/PDFGraphics_Spec.swift index ed17cfbc..438e4ed5 100644 --- a/Tests/TPPDFTests/Graphics/PDFGraphics_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFGraphics_Spec.swift @@ -6,17 +6,15 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF -class PDFGraphics_Spec : QuickSpec { - +class PDFGraphics_Spec: QuickSpec { override func spec() { describe("PDFGraphics") { - it("can create dashes with butts") { let width: CGFloat = 5 let style = PDFLineStyle(type: .dashed, color: .red, width: width) @@ -44,7 +42,6 @@ class PDFGraphics_Spec : QuickSpec { } describe("resizing and compression") { - let base64String = "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" let data: Data! = Data(base64Encoded: base64String) diff --git a/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject+Equatable_Spec.swift b/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject+Equatable_Spec.swift index 1216863d..b6e5a46b 100644 --- a/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLineSeparatorObject_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFLineSeparatorObject") { - context("Equatable") { - it("is equal") { let style = PDFLineStyle(type: .dotted, color: .orange, width: 0.25) diff --git a/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject_Spec.swift b/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject_Spec.swift index de29ea0a..411e4045 100644 --- a/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFLineSeparatorObject_Spec.swift @@ -7,26 +7,22 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFLineSeparatorObject_Spec: QuickSpec { - override func spec() { describe("PDFLineSeparatorObject") { - var separator: PDFLineSeparatorObject! = PDFLineSeparatorObject() context("variables") { - it("has a line style") { expect(separator.style).toNot(beNil()) } } context("initializers") { - it("can be initialized without") { separator = PDFLineSeparatorObject() expect(separator).toNot(beNil()) @@ -58,7 +54,6 @@ class PDFLineSeparatorObject_Spec: QuickSpec { } context("drawing") { - let document = PDFDocument(layout: PDFPageLayout(size: CGSize(width: 50, height: 50), margin: EdgeInsets(top: 10, left: 10, bottom: 10, right: 10), space: (header: 5, footer: 5))) @@ -91,7 +86,7 @@ class PDFLineSeparatorObject_Spec: QuickSpec { // expected = separator.style.color.hex // } // // TODO: add pixel testing -//// expect(result).to(equal(expected), description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") + //// expect(result).to(equal(expected), description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") // // // Early exit to only fail at first error! // if result != expected { diff --git a/Tests/TPPDFTests/Graphics/PDFLineStyle_Equatable_Spec.swift b/Tests/TPPDFTests/Graphics/PDFLineStyle_Equatable_Spec.swift index 529faaeb..b3c1164e 100644 --- a/Tests/TPPDFTests/Graphics/PDFLineStyle_Equatable_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFLineStyle_Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLineStyle_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFLineStyle") { - context("Equatable") { - it("is equal") { let style1 = PDFLineStyle(type: .dotted, color: .orange, width: 0.25) let style2 = PDFLineStyle(type: .dotted, color: .orange, width: 0.25) diff --git a/Tests/TPPDFTests/Graphics/PDFLineStyle_Spec.swift b/Tests/TPPDFTests/Graphics/PDFLineStyle_Spec.swift index 4dfc34a6..31c7cad4 100644 --- a/Tests/TPPDFTests/Graphics/PDFLineStyle_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFLineStyle_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFLineStyle_Spec: QuickSpec { - override func spec() { describe("Line Style") { - var lineStyle: PDFLineStyle! let type = PDFLineType.dotted @@ -41,7 +39,6 @@ class PDFLineStyle_Spec: QuickSpec { } context("variables") { - beforeEach { lineStyle = PDFLineStyle(type: type, color: color, width: width) } diff --git a/Tests/TPPDFTests/Graphics/PDFLineType_Spec.swift b/Tests/TPPDFTests/Graphics/PDFLineType_Spec.swift index 1ff66c4a..c16b018e 100644 --- a/Tests/TPPDFTests/Graphics/PDFLineType_Spec.swift +++ b/Tests/TPPDFTests/Graphics/PDFLineType_Spec.swift @@ -6,16 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLineType_Spec: QuickSpec { - override func spec() { - describe("PDFLineType") { - - } + describe("PDFLineType") {} } static var allTests = [ diff --git a/Tests/TPPDFTests/Graphics/UIColor+Hex_Spec.swift b/Tests/TPPDFTests/Graphics/UIColor+Hex_Spec.swift deleted file mode 100644 index 9085d44c..00000000 --- a/Tests/TPPDFTests/Graphics/UIColor+Hex_Spec.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// Color+Hex_Spec.swift -// TPPDF_Tests -// -// Created by Philip Niedertscheider on 09/11/2017. -// Copyright © 2017 CocoaPods. All rights reserved. -// - -import Quick -import Nimble -@testable import TPPDF - -class Color_Hex_Spec: QuickSpec { - - override func spec() { - describe("Color+Hex") { - - it("can be initialized with three digit hex") { - let color = try? Color(hex: "3F0") - expect(color) == Color(red: 0.2, green: 1.0, blue: 0, alpha: 1) - } - - it("can be initialized with four digit hex") { - let color = try? Color(hex: "3F0C") - expect(color) == Color(red: 0.2, green: 1.0, blue: 0, alpha: 0.8) - } - - it("can be initialized with six digit hex") { - let color = try? Color(hex: "FF00FF") - expect(color) == Color.magenta - } - - it("can be initialized with eight digit hex") { - let color = try? Color(hex: "FFFF0000") - expect(color) == Color.yellow.withAlphaComponent(0.0) - } - - it("can not be initialized with other length") { - expect { - try Color(hex: "1234567890") - }.to(throwError()) - } - - it("can not be initialized with invalid hexadecimal characters") { - expect { - try Color(hex: "%") - }.to(throwError()) - } - - it("can be converted to hexadecimal string") { - expect(Color.orange.hex) == "#ff7f00" - expect(Color.orange.withAlphaComponent(0.5).hex) == "#ff7f007f" - } - } - } - -} diff --git a/Tests/TPPDFTests/Graphics/UIImage+CloseToEqual_Spec.swift b/Tests/TPPDFTests/Graphics/UIImage+CloseToEqual_Spec.swift index c64cd2c7..4b20be70 100644 --- a/Tests/TPPDFTests/Graphics/UIImage+CloseToEqual_Spec.swift +++ b/Tests/TPPDFTests/Graphics/UIImage+CloseToEqual_Spec.swift @@ -6,19 +6,16 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class UIImage_CloseToEqual_Spec: QuickSpec { - override func spec() { describe("UIImage") { - let color = Color(red: 0.8, green: 0.7, blue: 0.6, alpha: 0.5) context("CloseToEqual") { - it("is close to equal if difference is smaller than delta") { let otherColor = Color(red: 0.79999, green: 0.69999, blue: 0.59999, alpha: 0.49999) expect(color.isClose(to: otherColor, decimals: 5)).to(beTrue()) @@ -49,5 +46,4 @@ class UIImage_CloseToEqual_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Graphics/UIImage+Pixel_Spec.swift b/Tests/TPPDFTests/Graphics/UIImage+Pixel_Spec.swift deleted file mode 100644 index 7095194d..00000000 --- a/Tests/TPPDFTests/Graphics/UIImage+Pixel_Spec.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// Image+Pixel_Spec.swift -// TPPDF_Tests -// -// Created by Philip Niedertscheider on 05/11/2017. -// Copyright © 2017 CocoaPods. All rights reserved. -// - -import CoreGraphics -import Quick -import Nimble -@testable import TPPDF - -class Image_Pixel_Spec: QuickSpec { - - override func spec() { - describe("Image") { - - context("Pixel") { - it("can get pixel color") { - let size = CGSize(width: 2, height: 2) - let context = PDFContextGraphics.createBitmapContext(size: size)! - - context.setFillColor(Color.blue.cgColor) - context.fill(.init(x: 0, y: 0, width: 1, height: 1)) - - context.setFillColor(Color.green.cgColor) - context.fill(.init(x: 1, y: 0, width: 1, height: 1)) - - context.setFillColor(Color.red.cgColor) - context.fill(.init(x: 0, y: 1, width: 1, height: 1)) - - context.setFillColor(Color.orange.cgColor) - context.fill(.init(x: 1, y: 1, width: 1, height: 1)) - - let image = PDFContextGraphics.getImage(from: context, size: size)! - - // Position is upside down - - expect(image.size) == CGSize(width: 2, height: 2) - expect(image.pixelColor(at: CGPoint(x: 0, y: 1))) == Color.blue - expect(image.pixelColor(at: CGPoint(x: 1, y: 1))) == Color.green - expect(image.pixelColor(at: CGPoint(x: 0, y: 0))) == Color.red - expect(image.pixelColor(at: CGPoint(x: 1, y: 0)).isClose(to: Color.orange, decimals: 2)).to(beTrue()) - } - } - } - } - -} diff --git a/Tests/TPPDFTests/Image/PDFImageSizeFit_Spec.swift b/Tests/TPPDFTests/Image/PDFImageSizeFit_Spec.swift index f0ba92f9..2274b831 100644 --- a/Tests/TPPDFTests/Image/PDFImageSizeFit_Spec.swift +++ b/Tests/TPPDFTests/Image/PDFImageSizeFit_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFImageSizeFit_Spec: QuickSpec { - override func spec() { describe("PDFImageSizeFit") { - it("should have enum values") { expect(PDFImageSizeFit.width).toNot(beNil()) expect(PDFImageSizeFit.height).toNot(beNil()) @@ -22,5 +20,4 @@ class PDFImageSizeFit_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Image/PDFImage_Equatable_Spec.swift b/Tests/TPPDFTests/Image/PDFImage_Equatable_Spec.swift index 1808a343..cf55ac69 100644 --- a/Tests/TPPDFTests/Image/PDFImage_Equatable_Spec.swift +++ b/Tests/TPPDFTests/Image/PDFImage_Equatable_Spec.swift @@ -6,17 +6,15 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFImage_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFImage") { - let base64String = "/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAAQABAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLv/dAAQAAf/aAAwDAQACEQMRAD8A6+iiivxY/Sz/2Q==".data(using: String.Encoding.utf8)! let data = Data(base64Encoded: base64String)! let image = Image(data: data)! @@ -99,5 +97,4 @@ class PDFImage_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Image/PDFImage_Spec.swift b/Tests/TPPDFTests/Image/PDFImage_Spec.swift index dad45d18..4c259996 100644 --- a/Tests/TPPDFTests/Image/PDFImage_Spec.swift +++ b/Tests/TPPDFTests/Image/PDFImage_Spec.swift @@ -6,17 +6,15 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFImage_Spec: QuickSpec { - override func spec() { describe("PDFImage") { - let base64String = "/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAAQABAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLv/dAAQAAf/aAAwDAQACEQMRAD8A6+iiivxY/Sz/2Q==".data(using: String.Encoding.utf8)! let data = Data(base64Encoded: base64String)! let image = Image(data: data)! @@ -34,7 +32,6 @@ class PDFImage_Spec: QuickSpec { } context("initializer") { - it("can be initialized with only an image") { pdfImage = PDFImage(image: image) expect(pdfImage.image) == image @@ -46,7 +43,6 @@ class PDFImage_Spec: QuickSpec { } context("variables") { - it("has an image") { expect(pdfImage.image) == image } @@ -73,5 +69,4 @@ class PDFImage_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Internal/Table/PDFTableMergeUtil_Spec.swift b/Tests/TPPDFTests/Internal/Table/PDFTableMergeUtil_Spec.swift index f8a2582e..37291c9d 100644 --- a/Tests/TPPDFTests/Internal/Table/PDFTableMergeUtil_Spec.swift +++ b/Tests/TPPDFTests/Internal/Table/PDFTableMergeUtil_Spec.swift @@ -7,15 +7,13 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableMergeUtilSpec: QuickSpec { - override func spec() { describe("PDFTableMergeUtil") { - let ROWS = 10 let COLS = 10 @@ -31,7 +29,6 @@ class PDFTableMergeUtilSpec: QuickSpec { } context("no merging") { - it("should return a node for each cell") { let result = PDFTableMergeUtil.calculateMerged(table: table) expect(result).to(haveCount(ROWS)) @@ -50,7 +47,6 @@ class PDFTableMergeUtilSpec: QuickSpec { } context("with merging") { - it("should return a node with merged row span") { for row in 0.. PDFTable { - let table = PDFTable(rows: rows, columns: columns) - table.widths = [0.1, 0.3, 0.3, 0.3] - table.margin = 10 - table.padding = 10 - table.shouldSplitCellsOnPageBreak = false - table.style.columnHeaderCount = 3 - - for row in 0.. PDFTable { + let table = PDFTable(rows: rows, columns: columns) + table.widths = [0.1, 0.3, 0.3, 0.3] + table.margin = 10 + table.padding = 10 + table.shouldSplitCellsOnPageBreak = false + table.style.columnHeaderCount = 3 + + for row in 0.. [PDFLocatedRenderObject] { - let container = PDFContainer.contentLeft - let generator = PDFGenerator(document: .init(format: .a4)) - let tableObject = PDFTableObject(table: table) - return try tableObject.calculate(generator: generator, container: container) + private func calculate(table: PDFTable) throws -> [PDFLocatedRenderObject] { + let container = PDFContainer.contentLeft + let generator = PDFGenerator(document: .init(format: .a4)) + let tableObject = PDFTableObject(table: table) + return try tableObject.calculate(generator: generator, container: container) + } } -} #endif diff --git a/Tests/TPPDFTests/Layout/PDFContainer_Spec.swift b/Tests/TPPDFTests/Layout/PDFContainer_Spec.swift index a7b9b6e8..f46627e7 100644 --- a/Tests/TPPDFTests/Layout/PDFContainer_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFContainer_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFContainer_Spec: QuickSpec { - override func spec() { describe("PDFContainer") { - it("should have enum values") { expect(PDFContainer.none).toNot(beNil()) @@ -104,5 +102,4 @@ class PDFContainer_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFIndentationObject_Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFIndentationObject_Equatable_Spec.swift index 7aacd529..eff14f56 100644 --- a/Tests/TPPDFTests/Layout/PDFIndentationObject_Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFIndentationObject_Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFIndentationObject_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFIndentationObject") { - context("Equatable") { - let object = PDFIndentationObject(indentation: 0, left: true, insideSectionColumn: true) it("is equal") { @@ -41,5 +38,4 @@ class PDFIndentationObject_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFIndentationObject_Spec.swift b/Tests/TPPDFTests/Layout/PDFIndentationObject_Spec.swift index 45c56502..00d19c09 100644 --- a/Tests/TPPDFTests/Layout/PDFIndentationObject_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFIndentationObject_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFIndentationObject_Spec: QuickSpec { - override func spec() { describe("PDFIndentationObject") { - var object: PDFIndentationObject! let indentation: CGFloat = 20.0 let left = false @@ -26,7 +24,6 @@ class PDFIndentationObject_Spec: QuickSpec { } describe("variables") { - it("has an indentation") { expect(object.indentation) == indentation } @@ -41,7 +38,6 @@ class PDFIndentationObject_Spec: QuickSpec { } describe("calculation") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! @@ -58,7 +54,7 @@ class PDFIndentationObject_Spec: QuickSpec { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.layout.indentation.leftIn(container: PDFContainer.contentLeft)).toEventually(equal(object.indentation)) expect(result).toEventually(haveCount(1)) @@ -70,10 +66,9 @@ class PDFIndentationObject_Spec: QuickSpec { object.left = false expect { result = try object.calculate(generator: generator, container: PDFContainer.contentLeft) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.layout.indentation.rightIn(container: PDFContainer.contentLeft)).toEventually(equal(object.indentation)) - expect(result).toEventually(haveCount(1)) expect(result.first?.0).toEventually(equal(container)) expect(result.first?.1 as? PDFIndentationObject).toEventually(equal(object)) @@ -81,5 +76,4 @@ class PDFIndentationObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayout+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayout+Equatable_Spec.swift index b017e9c3..4934a7df 100644 --- a/Tests/TPPDFTests/Layout/PDFLayout+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayout+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayout_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFLayout") { - context("Equatable") { - let layout = PDFLayout() it("is equal") { @@ -40,5 +37,4 @@ class PDFLayout_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayoutHeights+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayoutHeights+Equatable_Spec.swift index e93e41fe..99dac2ff 100644 --- a/Tests/TPPDFTests/Layout/PDFLayoutHeights+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayoutHeights+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayoutHeights_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFLayoutHeights") { - context("Equatable") { - let heights = PDFLayoutHeights() it("is equal") { @@ -44,5 +41,4 @@ class PDFLayoutHeights_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayoutHeights_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayoutHeights_Spec.swift index a5937fb1..908f6b90 100644 --- a/Tests/TPPDFTests/Layout/PDFLayoutHeights_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayoutHeights_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayoutHeights_Spec: QuickSpec { - override func spec() { describe("PDFLayoutHeights") { - var heights: PDFLayoutHeights! beforeEach { @@ -23,12 +21,11 @@ class PDFLayoutHeights_Spec: QuickSpec { } context("variables") { - it("has default values per header container") { expect(heights.header) == [ PDFContainer.headerLeft: 0, PDFContainer.headerCenter: 0, - PDFContainer.headerRight: 0 + PDFContainer.headerRight: 0, ] } @@ -36,7 +33,7 @@ class PDFLayoutHeights_Spec: QuickSpec { expect(heights.footer) == [ PDFContainer.footerLeft: 0, PDFContainer.footerCenter: 0, - PDFContainer.footerRight: 0 + PDFContainer.footerRight: 0, ] } @@ -50,7 +47,7 @@ class PDFLayoutHeights_Spec: QuickSpec { heights.header = [ PDFContainer.headerLeft: 2, PDFContainer.headerCenter: 3, - PDFContainer.headerRight: max + PDFContainer.headerRight: max, ] expect(heights.maxHeaderHeight()) == max } @@ -69,12 +66,12 @@ class PDFLayoutHeights_Spec: QuickSpec { heights.header = [ PDFContainer.headerLeft: 10, PDFContainer.headerCenter: 20, - PDFContainer.headerRight: 30 + PDFContainer.headerRight: 30, ] heights.footer = [ PDFContainer.footerLeft: 40, PDFContainer.footerCenter: 50, - PDFContainer.footerRight: 60 + PDFContainer.footerRight: 60, ] heights.content = 70 @@ -87,7 +84,6 @@ class PDFLayoutHeights_Spec: QuickSpec { heights.add(10, to: .headerRight) expect(heights.header[PDFContainer.headerRight]) == 40 - heights.add(10, to: .footerLeft) expect(heights.footer[PDFContainer.footerLeft]) == 50 @@ -119,5 +115,4 @@ class PDFLayoutHeights_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayoutIndentations+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayoutIndentations+Equatable_Spec.swift index 9be34a49..43f0c27d 100644 --- a/Tests/TPPDFTests/Layout/PDFLayoutIndentations+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayoutIndentations+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayoutIndentations_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFLayoutIndentations") { - context("Equatable") { - let indentation = PDFLayoutIndentations() it("is equal") { @@ -44,5 +41,4 @@ class PDFLayoutIndentations_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayoutIndentations_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayoutIndentations_Spec.swift index 45abb0d2..6389667f 100644 --- a/Tests/TPPDFTests/Layout/PDFLayoutIndentations_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayoutIndentations_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayoutIndentations_Spec: QuickSpec { - override func spec() { describe("PDFLayoutHeights") { - var indentations: PDFLayoutIndentations! beforeEach { @@ -22,7 +20,6 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("variables") { - it("has default header values") { expect(indentations.header.left) == 0 expect(indentations.header.right) == 0 @@ -40,7 +37,6 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("accessors") { - beforeEach { indentations.header = (10, 20) indentations.content = (30, 40) @@ -48,7 +44,6 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("left") { - it("can get value of header containers") { expect(indentations.leftIn(container: PDFContainer.headerLeft)) == 10 expect(indentations.leftIn(container: PDFContainer.headerCenter)) == 10 @@ -69,7 +64,6 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("right") { - it("can get value of header containers") { expect(indentations.rightIn(container: PDFContainer.headerLeft)) == 20 expect(indentations.rightIn(container: PDFContainer.headerCenter)) == 20 @@ -91,9 +85,7 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("modifiers") { - context("left") { - it("can set a value to a header container") { indentations.setLeft(indentation: 10, in: PDFContainer.headerLeft) expect(indentations.leftIn(container: PDFContainer.headerLeft)) == 10 @@ -129,7 +121,6 @@ class PDFLayoutIndentations_Spec: QuickSpec { } context("right") { - it("can set a value to a header container") { indentations.setRight(indentation: 10, in: PDFContainer.headerLeft) expect(indentations.rightIn(container: PDFContainer.headerLeft)) == 10 @@ -166,5 +157,4 @@ class PDFLayoutIndentations_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFLayout_Spec.swift b/Tests/TPPDFTests/Layout/PDFLayout_Spec.swift index 4994ecc6..d866d545 100644 --- a/Tests/TPPDFTests/Layout/PDFLayout_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFLayout_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFLayout_Spec: QuickSpec { - override func spec() { describe("PDFLayout") { - var layout: PDFLayout! beforeEach { @@ -23,7 +21,6 @@ class PDFLayout_Spec: QuickSpec { } context("variables") { - it("has an default heights instance") { layout.heights = PDFLayoutHeights() } @@ -37,7 +34,7 @@ class PDFLayout_Spec: QuickSpec { let headerHeights: [PDFContainer: CGFloat] = [ PDFContainer.headerLeft: 1, PDFContainer.headerCenter: 2, - PDFContainer.headerRight: 3 + PDFContainer.headerRight: 3, ] layout.heights.header = headerHeights @@ -48,7 +45,7 @@ class PDFLayout_Spec: QuickSpec { let footerHeights: [PDFContainer: CGFloat] = [ PDFContainer.footerLeft: 1, PDFContainer.footerCenter: 2, - PDFContainer.footerRight: 3 + PDFContainer.footerRight: 3, ] layout.heights.footer = footerHeights @@ -86,5 +83,4 @@ class PDFLayout_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFOffsetObject+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFOffsetObject+Equatable_Spec.swift index fa437a6c..37072336 100644 --- a/Tests/TPPDFTests/Layout/PDFOffsetObject+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFOffsetObject+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFOffsetObject_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFOffsetObject") { - context("Equatable") { - let object = PDFOffsetObject(offset: 10) it("is equal") { @@ -31,5 +28,4 @@ class PDFOffsetObject_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFOffsetObject_Spec.swift b/Tests/TPPDFTests/Layout/PDFOffsetObject_Spec.swift index ee1aac13..8c5c9062 100644 --- a/Tests/TPPDFTests/Layout/PDFOffsetObject_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFOffsetObject_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFOffsetObject_Spec: QuickSpec { - override func spec() { describe("PDFOffsetObject") { - var object: PDFOffsetObject! let offset: CGFloat = 20.0 @@ -24,14 +22,12 @@ class PDFOffsetObject_Spec: QuickSpec { } describe("variables") { - it("has an offset value") { expect(object.offset) == offset } } describe("calculation") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! @@ -46,7 +42,7 @@ class PDFOffsetObject_Spec: QuickSpec { it("can set offset") { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.layout.getContentOffset(in: container)).toEventually(equal(object.offset)) expect(result).toEventually(haveCount(1)) @@ -56,5 +52,4 @@ class PDFOffsetObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFPageBreakObject+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFPageBreakObject+Equatable_Spec.swift index 8b9af5ea..df85d0b9 100644 --- a/Tests/TPPDFTests/Layout/PDFPageBreakObject+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFPageBreakObject+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageBreakObject_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFPageBreakObject") { - context("Equatable") { - let object = PDFPageBreakObject() it("is equal") { @@ -26,5 +23,4 @@ class PDFPageBreakObject_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFPageBreakObject_Spec.swift b/Tests/TPPDFTests/Layout/PDFPageBreakObject_Spec.swift index 56850899..6a32a2cf 100644 --- a/Tests/TPPDFTests/Layout/PDFPageBreakObject_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFPageBreakObject_Spec.swift @@ -6,17 +6,15 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFPageBreakObject_Spec: QuickSpec { - override func spec() { describe("PDFPageBreakObject") { - var object: PDFPageBreakObject! beforeEach { @@ -24,7 +22,6 @@ class PDFPageBreakObject_Spec: QuickSpec { } describe("calculation and drawing") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! var context: CGContext! @@ -43,7 +40,7 @@ class PDFPageBreakObject_Spec: QuickSpec { it("can set offset") { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.layout.heights.content) == 0 expect(result).toEventually(haveCount(1)) @@ -59,5 +56,4 @@ class PDFPageBreakObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFPageLayout+Equatable_Spec.swift b/Tests/TPPDFTests/Layout/PDFPageLayout+Equatable_Spec.swift index ab1d4177..8e4e0383 100644 --- a/Tests/TPPDFTests/Layout/PDFPageLayout+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFPageLayout+Equatable_Spec.swift @@ -7,17 +7,14 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageLayout_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFPageLayout") { - context("Equatable") { - var object: PDFPageLayout! beforeEach { @@ -58,5 +55,4 @@ class PDFPageLayout_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFPageLayout_Spec.swift b/Tests/TPPDFTests/Layout/PDFPageLayout_Spec.swift index 9965ea3e..f58362d7 100644 --- a/Tests/TPPDFTests/Layout/PDFPageLayout_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFPageLayout_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageLayout_Spec: QuickSpec { - override func spec() { describe("PDFPageLayout") { - var layout: PDFPageLayout! beforeEach { @@ -23,7 +21,6 @@ class PDFPageLayout_Spec: QuickSpec { } context("variables") { - it("has default value size") { expect(layout.size) == CGSize.zero } @@ -39,7 +36,6 @@ class PDFPageLayout_Spec: QuickSpec { } context("computed variables") { - it("has a value bounds") { layout.size = CGSize(width: 10, height: 20) expect(layout.bounds) == CGRect(x: 0, y: 0, width: 10, height: 20) @@ -57,5 +53,4 @@ class PDFPageLayout_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Layout/PDFSpaceObject_Spec.swift b/Tests/TPPDFTests/Layout/PDFSpaceObject_Spec.swift index e9ffc2d7..61fe6ca7 100644 --- a/Tests/TPPDFTests/Layout/PDFSpaceObject_Spec.swift +++ b/Tests/TPPDFTests/Layout/PDFSpaceObject_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFSpaceObject_Spec: QuickSpec { - override func spec() { describe("PDFSpaceObject") { - var object: PDFSpaceObject! let space: CGFloat = 20.0 @@ -24,14 +22,12 @@ class PDFSpaceObject_Spec: QuickSpec { } describe("variables") { - it("has an space value") { expect(object.space) == space } } context("calculation") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! @@ -48,7 +44,7 @@ class PDFSpaceObject_Spec: QuickSpec { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.layout.heights.content).toEventually(equal(contentHeight + object.frame.height)) expect(object.frame) == CGRect(x: 60, y: 60, width: 475, height: space) @@ -60,7 +56,6 @@ class PDFSpaceObject_Spec: QuickSpec { } context("rendering") { - let document = PDFDocument(layout: PDFPageLayout(size: CGSize(width: 60, height: 60), margin: EdgeInsets(top: 10, left: 10, bottom: 10, right: 10), space: (header: 5, footer: 5))) @@ -171,5 +166,4 @@ class PDFSpaceObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFList+Equatable_Spec.swift b/Tests/TPPDFTests/List/PDFList+Equatable_Spec.swift index b5139e21..806a8e7d 100644 --- a/Tests/TPPDFTests/List/PDFList+Equatable_Spec.swift +++ b/Tests/TPPDFTests/List/PDFList+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFList_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFList") { - context("Equatable") { - var object: PDFList! beforeEach { @@ -48,5 +45,4 @@ class PDFList_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFListItemObject_Spec.swift b/Tests/TPPDFTests/List/PDFListItemObject_Spec.swift index be6e01d6..367c81a2 100644 --- a/Tests/TPPDFTests/List/PDFListItemObject_Spec.swift +++ b/Tests/TPPDFTests/List/PDFListItemObject_Spec.swift @@ -6,17 +6,15 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFListItemObject_Spec: QuickSpec { - override func spec() { describe("PDFListObject") { - let list = PDFList(indentations: [(pre: 10, past: 10), (pre: 20, past: 10)]) list.addItem(PDFListItem(symbol: .numbered(value: "1"), content: "Heading 1")) .addItem(PDFListItem(symbol: .numbered(value: nil), content: "Heading 2")) @@ -29,14 +27,12 @@ class PDFListItemObject_Spec: QuickSpec { let object = PDFListObject(list: list) context("variables") { - it("has a list") { expect(object.list) == list } } context("calculations") { - let document = PDFDocument(format: .a4) let container = PDFContainer.contentLeft var generator: PDFGenerator! @@ -62,9 +58,9 @@ class PDFListItemObject_Spec: QuickSpec { expect(item?.frame.origin.y).to(equal(60)) expect(item?.frame.size.width).to(beCloseTo(12, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "1."))) @@ -75,9 +71,9 @@ class PDFListItemObject_Spec: QuickSpec { expect(item?.frame.origin.y).to(equal(60)) expect(item?.frame.size.width).to(beCloseTo(75, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Heading 1"))) @@ -86,15 +82,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[2].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 10)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(80)) + expect(item?.frame.origin.y).to(equal(80)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(81)) + expect(item?.frame.origin.y).to(equal(81)) #endif expect(item?.frame.size.width).to(beCloseTo(13, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "?."))) @@ -103,15 +99,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[3].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 20)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(80)) + expect(item?.frame.origin.y).to(equal(80)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(81)) + expect(item?.frame.origin.y).to(equal(81)) #endif expect(item?.frame.size.width).to(beCloseTo(78, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Heading 2"))) @@ -120,15 +116,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[4].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 10)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(100)) + expect(item?.frame.origin.y).to(equal(100)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(102)) + expect(item?.frame.origin.y).to(equal(102)) #endif expect(item?.frame.size.width).to(beCloseTo(4, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: PDFListItemSymbol.dot.stringValue))) @@ -137,15 +133,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[5].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 20)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(100)) + expect(item?.frame.origin.y).to(equal(100)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(102)) + expect(item?.frame.origin.y).to(equal(102)) #endif expect(item?.frame.size.width).to(beCloseTo(79, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Heading 3"))) @@ -154,15 +150,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[6].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 20)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(120)) + expect(item?.frame.origin.y).to(equal(120)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(123)) + expect(item?.frame.origin.y).to(equal(123)) #endif expect(item?.frame.size.width).to(beCloseTo(8, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: PDFListItemSymbol.dash.stringValue))) @@ -171,15 +167,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[7].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 30)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(120)) + expect(item?.frame.origin.y).to(equal(120)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(123)) + expect(item?.frame.origin.y).to(equal(123)) #endif expect(item?.frame.size.width).to(beCloseTo(103, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Subheading 1"))) @@ -188,15 +184,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[8].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 30)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(140)) + expect(item?.frame.origin.y).to(equal(140)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(144)) + expect(item?.frame.origin.y).to(equal(144)) #endif expect(item?.frame.size.width).to(beCloseTo(106, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Subheading 2"))) @@ -205,15 +201,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[9].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 20)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(160)) + expect(item?.frame.origin.y).to(equal(160)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(165)) + expect(item?.frame.origin.y).to(equal(165)) #endif expect(item?.frame.size.width).to(beCloseTo(4, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: PDFListItemSymbol.dot.stringValue))) @@ -222,15 +218,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[10].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 30)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(160)) + expect(item?.frame.origin.y).to(equal(160)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(165)) + expect(item?.frame.origin.y).to(equal(165)) #endif expect(item?.frame.size.width).to(beCloseTo(105.4, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Subheading 3"))) @@ -239,15 +235,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[11].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 10)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(180)) + expect(item?.frame.origin.y).to(equal(180)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(186)) + expect(item?.frame.origin.y).to(equal(186)) #endif expect(item?.frame.size.width).to(beCloseTo(11, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "+"))) @@ -256,15 +252,15 @@ class PDFListItemObject_Spec: QuickSpec { item = result?[12].1 as? PDFAttributedTextObject expect(item?.frame.origin.x).to(equal(document.layout.margin.left + 20)) #if os(macOS) - expect(item?.frame.origin.y).to(equal(180)) + expect(item?.frame.origin.y).to(equal(180)) #elseif os(iOS) - expect(item?.frame.origin.y).to(equal(186)) + expect(item?.frame.origin.y).to(equal(186)) #endif expect(item?.frame.size.width).to(beCloseTo(79, within: 1)) #if os(macOS) - expect(item?.frame.size.height).to(equal(20.0)) + expect(item?.frame.size.height).to(equal(20.0)) #elseif os(iOS) - expect(item?.frame.size.height).to(equal(21.0)) + expect(item?.frame.size.height).to(equal(21.0)) #endif expect(item?.simpleText).to(equal(PDFSimpleText(text: "Heading 4"))) } @@ -275,7 +271,7 @@ class PDFListItemObject_Spec: QuickSpec { expect { result = try? object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(result).toNot(beNil()) expect(result?.count).to(equal(13)) @@ -290,9 +286,9 @@ class PDFListItemObject_Spec: QuickSpec { expect(item.frame.origin.y) == 60 expect(item.frame.size.width).to(beCloseTo(12, within: 1)) #if os(macOS) - expect(item.frame.size.height) == 20 + expect(item.frame.size.height) == 20 #elseif os(iOS) - expect(item.frame.size.height) == 21 + expect(item.frame.size.height) == 21 #endif expect(item.simpleText) == PDFSimpleText(text: "1.") @@ -306,9 +302,9 @@ class PDFListItemObject_Spec: QuickSpec { expect(otherItem.frame.origin.y) == 60 expect(otherItem.frame.size.width).to(beCloseTo(76, within: 1)) #if os(macOS) - expect(otherItem.frame.size.height) == 20 + expect(otherItem.frame.size.height) == 20 #elseif os(iOS) - expect(otherItem.frame.size.height) == 21 + expect(otherItem.frame.size.height) == 21 #endif expect(otherItem.simpleText) == PDFSimpleText(text: "Heading 1") @@ -317,5 +313,4 @@ class PDFListItemObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFListItemSymbol_Spec.swift b/Tests/TPPDFTests/List/PDFListItemSymbol_Spec.swift index a1547b60..e02fce7e 100644 --- a/Tests/TPPDFTests/List/PDFListItemSymbol_Spec.swift +++ b/Tests/TPPDFTests/List/PDFListItemSymbol_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF -class PDFListItemSymbol_Spec : QuickSpec { - +class PDFListItemSymbol_Spec: QuickSpec { override func spec() { describe("PDFListItemSymbol") { - it("should have enum values") { expect(PDFListItemSymbol.none).toNot(beNil()) expect(PDFListItemSymbol.inherit).toNot(beNil()) @@ -64,5 +62,4 @@ class PDFListItemSymbol_Spec : QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFListItem_Equatable_Spec.swift b/Tests/TPPDFTests/List/PDFListItem_Equatable_Spec.swift index f7914700..3d2bc15a 100644 --- a/Tests/TPPDFTests/List/PDFListItem_Equatable_Spec.swift +++ b/Tests/TPPDFTests/List/PDFListItem_Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFListItem_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFListItem") { - context("Equatable") { - var object: PDFListItem! beforeEach { @@ -54,5 +51,4 @@ class PDFListItem_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFListItem_Spec.swift b/Tests/TPPDFTests/List/PDFListItem_Spec.swift index 45a4fd10..98fe4fb3 100644 --- a/Tests/TPPDFTests/List/PDFListItem_Spec.swift +++ b/Tests/TPPDFTests/List/PDFListItem_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFListItem_Spec: QuickSpec { - override func spec() { describe("PDFListItem") { - var object: PDFListItem! beforeEach { @@ -22,7 +20,6 @@ class PDFListItem_Spec: QuickSpec { } describe("variables") { - it("has an optional parent") { expect(object.parent).to(beNil()) } @@ -41,7 +38,6 @@ class PDFListItem_Spec: QuickSpec { } describe("initializer") { - it("can be initialized with a symbol") { object = PDFListItem(symbol: .dash) expect(object.symbol.rawValue) == PDFListItemSymbol.dash.rawValue @@ -56,11 +52,10 @@ class PDFListItem_Spec: QuickSpec { } context("children") { - it("can add multiple items") { let items = [ PDFListItem(symbol: .dash, content: "A1"), - PDFListItem(symbol: .dot, content: "A2") + PDFListItem(symbol: .dot, content: "A2"), ] expect(object.addItems(items)) === object @@ -92,5 +87,4 @@ class PDFListItem_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/List/PDFList_Spec.swift b/Tests/TPPDFTests/List/PDFList_Spec.swift index d85cd172..ec98def2 100644 --- a/Tests/TPPDFTests/List/PDFList_Spec.swift +++ b/Tests/TPPDFTests/List/PDFList_Spec.swift @@ -5,15 +5,13 @@ // Created by Philip Niedertscheider on 13/06/2017. // -import Quick import Nimble +import Quick @testable import TPPDF class ListSpec: QuickSpec { - override func spec() { describe("PDFList") { - let list = PDFList(indentations: [(pre: 0.0, past: 10.0), (pre: 10.0, past: 10.0), (pre: 20.0, past: 10.0)]) it("has no items by default") { expect(list.count).to(equal(0)) @@ -52,25 +50,25 @@ class ListSpec: QuickSpec { PDFListItem(symbol: .none, content: "Child 2.2"), PDFListItem(content: "Child 2.3"), ] - ) + ), ] - ), + ), PDFListItem(symbol: .dash, content: "Base 2") .addItems( [ PDFListItem(content: "Child 2.1") .addItems( [ - PDFListItem(symbol: .dot, content: "Child 2.1.1") + PDFListItem(symbol: .dot, content: "Child 2.1.1"), ]), PDFListItem(content: "Child 2.2") .addItems( [ - PDFListItem(symbol: .dash, content: "Child 2.2.1") + PDFListItem(symbol: .dash, content: "Child 2.2.1"), ] - ) + ), ] - ) + ), ] ) @@ -117,5 +115,4 @@ class ListSpec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Math/CGPoint+Math_Spec.swift b/Tests/TPPDFTests/Math/CGPoint+Math_Spec.swift index 9ecf07f7..bd296783 100644 --- a/Tests/TPPDFTests/Math/CGPoint+Math_Spec.swift +++ b/Tests/TPPDFTests/Math/CGPoint+Math_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class CGPoint_Math_Spec: QuickSpec { - override func spec() { describe("CGPoint") { - let point = CGPoint(x: 10, y: 20) it("can be added to a CGPoint") { @@ -37,5 +35,4 @@ class CGPoint_Math_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Metadata/PDFInfo+Equatable_Spec.swift b/Tests/TPPDFTests/Metadata/PDFInfo+Equatable_Spec.swift index 62adfc3e..53fcdc67 100644 --- a/Tests/TPPDFTests/Metadata/PDFInfo+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Metadata/PDFInfo+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFInfo_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFInfo+Equatable") { - context("Equatable") { - var object: PDFInfo! beforeEach { @@ -90,5 +87,4 @@ class PDFInfo_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Metadata/PDFInfo_Spec.swift b/Tests/TPPDFTests/Metadata/PDFInfo_Spec.swift index ccc02ed1..6af5a3a8 100644 --- a/Tests/TPPDFTests/Metadata/PDFInfo_Spec.swift +++ b/Tests/TPPDFTests/Metadata/PDFInfo_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFInfo_Spec: QuickSpec { - override func spec() { describe("PDFInfo") { - var info: PDFInfo! beforeEach { @@ -23,7 +21,6 @@ class PDFInfo_Spec: QuickSpec { } context("default variables") { - it("should have default title") { expect(info.title) == "Title" } @@ -76,5 +73,4 @@ class PDFInfo_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/PDFDocument+Objects_Spec.swift b/Tests/TPPDFTests/PDFDocument+Objects_Spec.swift index be0ccaa1..897b9033 100644 --- a/Tests/TPPDFTests/PDFDocument+Objects_Spec.swift +++ b/Tests/TPPDFTests/PDFDocument+Objects_Spec.swift @@ -6,19 +6,16 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFDocument_Objects_Spec: QuickSpec { - override func spec() { describe("PDFDocument") { - context("Objects") { - var document: PDFDocument! beforeEach { @@ -26,7 +23,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("spacing") { - let value: CGFloat = 20 it("is possible to add into default container") { @@ -49,7 +45,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("line separator") { - let style = PDFLineStyle(type: .dotted, color: .red, width: 10) it("is possible to add into default container") { @@ -74,7 +69,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("image") { - let base64String = "/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAAQABAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLv/dAAQAAf/aAAwDAQACEQMRAD8A6+iiivxY/Sz/2Q==".data(using: String.Encoding.utf8)! let data = Data(base64Encoded: base64String)! let image = Image(data: data)! @@ -102,7 +96,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("rows") { - let images = [pdfImage, pdfImage, pdfImage] let spacing: CGFloat = 10.0 @@ -129,12 +122,9 @@ class PDFDocument_Objects_Spec: QuickSpec { } } - context("image row") { - - } + context("image row") {} context("simple text") { - let text = "EXAMPLE" let spacing: CGFloat = 2.5 @@ -163,7 +153,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("attributed text") { - let text = NSAttributedString(string: "EXAMPLE") it("is possible to add an attributed text to the default container") { @@ -190,7 +179,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("text font") { - let font = Font.systemFont(ofSize: 20, weight: .bold) it("is possible to set the text color of the default container") { @@ -235,7 +223,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("text color") { - let color = Color.orange it("is possible to set the text color of the default container") { @@ -280,7 +267,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("table") { - let table = PDFTable(rows: 0, columns: 0) it("is possible to add a table into the default container") { @@ -305,7 +291,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("list") { - let indentations: [(pre: CGFloat, past: CGFloat)] = [(pre: 0, past: 10)] let list = PDFList(indentations: indentations) @@ -331,7 +316,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("indentation") { - let indentation: CGFloat = 20.0 let leftSide = true @@ -359,7 +343,6 @@ class PDFDocument_Objects_Spec: QuickSpec { } context("absolute offset") { - let offset: CGFloat = 20.0 it("is possible to set absolute offset of default container") { @@ -393,5 +376,4 @@ class PDFDocument_Objects_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/PDFDocument_Spec.swift b/Tests/TPPDFTests/PDFDocument_Spec.swift index fc0c6c88..bc3898e3 100644 --- a/Tests/TPPDFTests/PDFDocument_Spec.swift +++ b/Tests/TPPDFTests/PDFDocument_Spec.swift @@ -6,16 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF -class PDFDocument_Spec : QuickSpec { - +class PDFDocument_Spec: QuickSpec { override func spec() { - describe("PDFDocument") { - let layout = PDFPageLayout() var document: PDFDocument! @@ -33,7 +30,6 @@ class PDFDocument_Spec : QuickSpec { } context("variables") { - it("should have layout") { expect(document.layout).toNot(beNil()) } @@ -52,5 +48,4 @@ class PDFDocument_Spec : QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/PDFGenerator+Debug_Spec.swift b/Tests/TPPDFTests/PDFGenerator+Debug_Spec.swift index 181e98c8..790bb1ee 100644 --- a/Tests/TPPDFTests/PDFGenerator+Debug_Spec.swift +++ b/Tests/TPPDFTests/PDFGenerator+Debug_Spec.swift @@ -7,17 +7,14 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFGenerator_Debug_Spec: QuickSpec { - override func spec() { describe("PDFGenerator") { - context("Debug") { - // let document = PDFDocument(layout: PDFPageLayout(size: CGSize(width: 50, height: 50), // margin: EdgeInsets(top: 10, left: 10, bottom: 10, right: 10), // space: (header: 5, footer: 5))) @@ -46,7 +43,7 @@ class PDFGenerator_Debug_Spec: QuickSpec { // let expected = Color.clear.hex // let result = pixel.hex // // TODO: add pixel testing -//// expect(result).to(equal(expected), description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") + //// expect(result).to(equal(expected), description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") // // // Early exit to only fail at first error! // if result != expected { @@ -87,9 +84,9 @@ class PDFGenerator_Debug_Spec: QuickSpec { // expected = Color.blue // } // -//// expect(result.isClose(to: expected, decimals: 2)) -//// .to(beTrue(), -//// description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") + //// expect(result.isClose(to: expected, decimals: 2)) + //// .to(beTrue(), + //// description: "Pixel at <\(x), \(y)> is expected to equal <\(expected)>, got <\(result)>") // // // Early exit to only fail at first error! // if result != expected { @@ -102,5 +99,4 @@ class PDFGenerator_Debug_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/PDFGenerator+Generation_Spec.swift b/Tests/TPPDFTests/PDFGenerator+Generation_Spec.swift index b0c5d667..f5f4d948 100644 --- a/Tests/TPPDFTests/PDFGenerator+Generation_Spec.swift +++ b/Tests/TPPDFTests/PDFGenerator+Generation_Spec.swift @@ -6,14 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFGenerator_Generation_Spec: QuickSpec { - override func spec() { describe("PDFGenerator") { context("Generation") { @@ -25,13 +24,13 @@ class PDFGenerator_Generation_Spec: QuickSpec { var url: URL! expect { url = try PDFGenerator(document: document).generateURL(filename: filename) - }.toNot(throwError()) + }.toNot(throwError()) expect(url).toEventuallyNot(beNil()) var writtenData: Data! expect { writtenData = try Data(contentsOf: url) - }.toNot(throwError()) + }.toNot(throwError()) expect(writtenData).toEventuallyNot(beNil()) // let expectedBase64 = "" @@ -45,13 +44,13 @@ class PDFGenerator_Generation_Spec: QuickSpec { var url: URL! expect { url = try PDFGenerator(document: document).generateURL(filename: filename) - }.toNot(throwError()) + }.toNot(throwError()) expect(url).toEventuallyNot(beNil()) var writtenData: Data! expect { writtenData = try Data(contentsOf: url) - }.toNot(throwError()) + }.toNot(throwError()) expect(writtenData).toEventuallyNot(beNil()) // let expectedBase64 = "" @@ -65,13 +64,13 @@ class PDFGenerator_Generation_Spec: QuickSpec { var url: URL! expect { url = try PDFGenerator(document: document).generateURL(filename: filename) - }.toNot(throwError()) + }.toNot(throwError()) expect(url).toEventuallyNot(beNil()) var writtenData: Data! expect { writtenData = try Data(contentsOf: url) - }.toNot(throwError()) + }.toNot(throwError()) expect(writtenData).toEventuallyNot(beNil()) // let expectedBase64 = "" @@ -81,14 +80,13 @@ class PDFGenerator_Generation_Spec: QuickSpec { } describe("data") { - it("should generate") { // let filename = "FILENAME" var data: Data! expect { data = try PDFGenerator(document: document).generateData() - }.toNot(throwError()) + }.toNot(throwError()) expect(data).toEventuallyNot(beNil()) // let expectedBase64 = "" // TODO: implement correct base64 @@ -101,7 +99,7 @@ class PDFGenerator_Generation_Spec: QuickSpec { var data: Data! expect { data = try PDFGenerator(document: document).generateData() - }.toNot(throwError()) + }.toNot(throwError()) expect(data).toEventuallyNot(beNil()) // let expectedBase64 = "" // TODO: implement correct base64 @@ -127,13 +125,11 @@ class PDFGenerator_Generation_Spec: QuickSpec { it("should render object") { class CustomObject: PDFRenderObject { - static var called = false - override func draw(generator: PDFGenerator, container: PDFContainer, in context: PDFContext) throws { + override func draw(generator _: PDFGenerator, container _: PDFContainer, in _: PDFContext) throws { CustomObject.called = true } - } let obj = CustomObject() @@ -150,7 +146,6 @@ class PDFGenerator_Generation_Spec: QuickSpec { } context("extract") { - let objs: [PDFLocatedRenderObject] = [ (PDFContainer.headerLeft, PDFSpaceObject(space: 10)), (PDFContainer.headerLeft, PDFSpaceObject(space: 10)), @@ -175,7 +170,7 @@ class PDFGenerator_Generation_Spec: QuickSpec { (PDFContainer.footerLeft, PDFSpaceObject(space: 10)), (PDFContainer.footerCenter, PDFSpaceObject(space: 10)), - (PDFContainer.footerRight, PDFSpaceObject(space: 10)) + (PDFContainer.footerRight, PDFSpaceObject(space: 10)), ] let headerObjs = objs[0...8] let contentObjs = objs[9...14] @@ -207,7 +202,6 @@ class PDFGenerator_Generation_Spec: QuickSpec { } describe("table of content") { - let headingStyle1 = document.add(style: PDFTextStyle(name: "Heading 1", font: Font.systemFont(ofSize: 25), color: Color.green)) let headingStyle2 = document.add(style: PDFTextStyle(name: "Heading 2", font: Font.systemFont(ofSize: 20), color: Color.red)) let headingStyle3 = document.add(style: PDFTextStyle(name: "Heading 3", font: Font.systemFont(ofSize: 18), color: Color.blue)) @@ -216,8 +210,8 @@ class PDFGenerator_Generation_Spec: QuickSpec { let styles = [ headingStyle1, headingStyle2, - headingStyle3 - ].map(WeakPDFTextStyleRef.init(value:)) + headingStyle3, + ].map(WeakPDFTextStyleRef.init(value:)) let textObjects = [ PDFSimpleText(text: "Heading 1", style: headingStyle1), @@ -246,16 +240,16 @@ class PDFGenerator_Generation_Spec: QuickSpec { PDFSimpleText(text: "Heading 3.1.1", style: headingStyle3), PDFSimpleText(text: "Body", style: bodyStyle), - PDFSimpleText(text: "Body", style: bodyStyle) + PDFSimpleText(text: "Body", style: bodyStyle), ] - let objs: [PDFLocatedRenderObject] = textObjects.map { return (PDFContainer.contentLeft, PDFAttributedTextObject(simpleText: $0)) } + let objs: [PDFLocatedRenderObject] = textObjects.map { (PDFContainer.contentLeft, PDFAttributedTextObject(simpleText: $0)) } it("should create list based on styles") { let list = PDFGenerator.createTableOfContentList(objects: objs, styles: styles, symbol: .dot) let expectedList = PDFList(indentations: [ (pre: CGFloat(10), past: CGFloat(10)), (pre: CGFloat(20), past: CGFloat(10)), - (pre: CGFloat(30), past: CGFloat(10)) + (pre: CGFloat(30), past: CGFloat(10)), ]) expectedList.addItems([ PDFListItem(symbol: .dot, content: textObjects[0].text) @@ -266,7 +260,7 @@ class PDFGenerator_Generation_Spec: QuickSpec { PDFListItem(symbol: .dot, content: textObjects[15].text) .addItem(PDFListItem(symbol: .none, content: nil) .addItem(PDFListItem(symbol: .dot, content: textObjects[18].text))), - ]) + ]) expect(list).to(equal(expectedList)) } @@ -274,7 +268,6 @@ class PDFGenerator_Generation_Spec: QuickSpec { } describe("total page estimation") { - // Test Case: // Precondition: // - Document contains an external document diff --git a/Tests/TPPDFTests/PDFGenerator+Layout_Spec.swift b/Tests/TPPDFTests/PDFGenerator+Layout_Spec.swift index 41aafa2f..3153b840 100644 --- a/Tests/TPPDFTests/PDFGenerator+Layout_Spec.swift +++ b/Tests/TPPDFTests/PDFGenerator+Layout_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFGenerator_Layout_Spec: QuickSpec { - override func spec() { describe("PDFGenerator+Layout") { - let document = PDFDocument(format: .a4) let generator = PDFGenerator(document: document) @@ -33,5 +31,4 @@ class PDFGenerator_Layout_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/PDFGenerator_Spec.swift b/Tests/TPPDFTests/PDFGenerator_Spec.swift index b0c5c363..b9b92806 100644 --- a/Tests/TPPDFTests/PDFGenerator_Spec.swift +++ b/Tests/TPPDFTests/PDFGenerator_Spec.swift @@ -6,20 +6,17 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFGenerator_Spec: QuickSpec { - override func spec() { describe("PDFGenerator") { - let document = PDFDocument(format: .a4) let generator = PDFGenerator(document: document) context("variables") { - it("has a document") { expect(generator.document).toNot(beNil()) } @@ -64,5 +61,4 @@ class PDFGenerator_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Page Format/PDFPageFormat+Layout_Spec.swift b/Tests/TPPDFTests/Page Format/PDFPageFormat+Layout_Spec.swift index 8782cce9..90ec1b8b 100644 --- a/Tests/TPPDFTests/Page Format/PDFPageFormat+Layout_Spec.swift +++ b/Tests/TPPDFTests/Page Format/PDFPageFormat+Layout_Spec.swift @@ -7,28 +7,25 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageFormat_Layout_Spec: QuickSpec { - override func spec() { describe("PDFPageFormat") { - context("layout") { - it("has a shorthand method to creaet a PDFPageLayout") { expect(PDFPageFormat.a0.layout) == PDFPageLayout(size: CGSize(width: 2384, height: 3370), margin: EdgeInsets( - top: 60.0, - left: 60.0, - bottom: 60.0, - right: 60.0), + top: 60.0, + left: 60.0, + bottom: 60.0, + right: 60.0 + ), space: (header: 15, footer: 15)) } } } } - } diff --git a/Tests/TPPDFTests/Page Format/PDFPageFormat+NameConstants_Spec.swift b/Tests/TPPDFTests/Page Format/PDFPageFormat+NameConstants_Spec.swift index 8e755a9f..0125d10c 100644 --- a/Tests/TPPDFTests/Page Format/PDFPageFormat+NameConstants_Spec.swift +++ b/Tests/TPPDFTests/Page Format/PDFPageFormat+NameConstants_Spec.swift @@ -1,17 +1,13 @@ import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageFormat_NameConstants_Spec: QuickSpec { - override func spec() { describe("PDFPagename") { - context("NameConstants") { - context("US Series") { - it("has a US Half Letter name") { expect(PDFPageFormat.usHalfLetter.name) == "US Half Letter" } @@ -34,7 +30,6 @@ class PDFPageFormat_NameConstants_Spec: QuickSpec { } context("ANSI Series") { - it("has a ANSI A name") { expect(PDFPageFormat.ansiA.name) == "ANSI A" } @@ -57,7 +52,6 @@ class PDFPageFormat_NameConstants_Spec: QuickSpec { } context("A Series") { - it("has a A0 name") { expect(PDFPageFormat.a0.name) == "A0" } @@ -104,7 +98,6 @@ class PDFPageFormat_NameConstants_Spec: QuickSpec { } context("B Series") { - it("has a B0 name") { expect(PDFPageFormat.b0.name) == "B0" } @@ -151,7 +144,6 @@ class PDFPageFormat_NameConstants_Spec: QuickSpec { } context("C Series") { - it("has a C0 name") { expect(PDFPageFormat.c0.name) == "C0" } @@ -199,5 +191,4 @@ class PDFPageFormat_NameConstants_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Page Format/PDFPageFormat+SizeConstants_Spec.swift b/Tests/TPPDFTests/Page Format/PDFPageFormat+SizeConstants_Spec.swift index 4a887d08..f72ae096 100644 --- a/Tests/TPPDFTests/Page Format/PDFPageFormat+SizeConstants_Spec.swift +++ b/Tests/TPPDFTests/Page Format/PDFPageFormat+SizeConstants_Spec.swift @@ -7,19 +7,15 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageFormat_SizeConstants_Spec: QuickSpec { - override func spec() { describe("PDFPageFormat") { - context("SizeConstants") { - context("US Series") { - it("has a US Half Letter format") { expect(PDFPageFormat.usHalfLetter.size) == CGSize(width: 396, height: 612) } @@ -42,7 +38,6 @@ class PDFPageFormat_SizeConstants_Spec: QuickSpec { } context("ANSI Series") { - it("has a ANSI A format") { expect(PDFPageFormat.ansiA.size) == CGSize(width: 612, height: 792) } @@ -65,7 +60,6 @@ class PDFPageFormat_SizeConstants_Spec: QuickSpec { } context("A Series") { - it("has a A0 format") { expect(PDFPageFormat.a0.size) == CGSize(width: 2384, height: 3370) } @@ -112,7 +106,6 @@ class PDFPageFormat_SizeConstants_Spec: QuickSpec { } context("B Series") { - it("has a B0 format") { expect(PDFPageFormat.b0.size) == CGSize(width: 2834, height: 4008) } @@ -159,7 +152,6 @@ class PDFPageFormat_SizeConstants_Spec: QuickSpec { } context("C Series") { - it("has a C0 format") { expect(PDFPageFormat.c0.size) == CGSize(width: 2599, height: 3677) } @@ -207,5 +199,4 @@ class PDFPageFormat_SizeConstants_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Page Format/PDFPageFormat_Spec.swift b/Tests/TPPDFTests/Page Format/PDFPageFormat_Spec.swift index e1dbe8d1..a43df3ab 100644 --- a/Tests/TPPDFTests/Page Format/PDFPageFormat_Spec.swift +++ b/Tests/TPPDFTests/Page Format/PDFPageFormat_Spec.swift @@ -6,17 +6,14 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFPageFormat_Spec: QuickSpec { - override func spec() { describe("PDFPageFormat") { - context("size") { - it("falls back to correct size") { expect(PDFPageFormat.c0.usSize) == PDFPageFormat.c0.size expect(PDFPageFormat.c0.ansiSize) == PDFPageFormat.c0.size @@ -34,5 +31,4 @@ class PDFPageFormat_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Pagination/Int+RomanNumerals_Spec.swift b/Tests/TPPDFTests/Pagination/Int+RomanNumerals_Spec.swift index 9fb0e116..0a3eb7f8 100644 --- a/Tests/TPPDFTests/Pagination/Int+RomanNumerals_Spec.swift +++ b/Tests/TPPDFTests/Pagination/Int+RomanNumerals_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class Int_RomanNUmerals_Spec: QuickSpec { - override func spec() { describe("Int") { - describe("RomanNumerals") { - it("can convert itself into a roman numeral") { expect(0.romanNumerals) == "" expect(1.romanNumerals) == "I" @@ -101,5 +98,4 @@ class Int_RomanNUmerals_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Pagination/PDFPaginationStyle+Equatable_Spec.swift b/Tests/TPPDFTests/Pagination/PDFPaginationStyle+Equatable_Spec.swift index 56ed3817..70e1f7f3 100644 --- a/Tests/TPPDFTests/Pagination/PDFPaginationStyle+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Pagination/PDFPaginationStyle+Equatable_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFPaginationStyle_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFPaginationStyle") { - context("Equatable") { - it("is equal when both default") { let lhsPagination = PDFPaginationStyle.default let rhsPagination = PDFPaginationStyle.default @@ -43,7 +40,6 @@ class PDFPaginationStyle_Equatable_Spec: QuickSpec { let secondFormatter = NumberFormatter() secondFormatter.numberStyle = NumberFormatter.Style.decimal - let firstTemplate = "123" let secondTemplate = "456" @@ -52,7 +48,7 @@ class PDFPaginationStyle_Equatable_Spec: QuickSpec { PDFPaginationStyle.customNumberFormat(template: firstTemplate, formatter: secondFormatter), PDFPaginationStyle.customNumberFormat(template: secondTemplate, formatter: firstFormatter), - PDFPaginationStyle.customNumberFormat(template: secondTemplate, formatter: secondFormatter) + PDFPaginationStyle.customNumberFormat(template: secondTemplate, formatter: secondFormatter), ] expect(paginations[0]) == paginations[0] @@ -77,8 +73,8 @@ class PDFPaginationStyle_Equatable_Spec: QuickSpec { } it("is never equal with custom closure") { - let pagination = PDFPaginationStyle.customClosure { (page, total) -> String in - return "" + let pagination = PDFPaginationStyle.customClosure { _, _ -> String in + "" } expect(pagination) != pagination expect(pagination.format(page: 1, total: 2)) == "" @@ -86,5 +82,4 @@ class PDFPaginationStyle_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Pagination/PDFPaginationStyle_Spec.swift b/Tests/TPPDFTests/Pagination/PDFPaginationStyle_Spec.swift index ff84f655..30365e25 100644 --- a/Tests/TPPDFTests/Pagination/PDFPaginationStyle_Spec.swift +++ b/Tests/TPPDFTests/Pagination/PDFPaginationStyle_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFPaginationStyle_Spec: QuickSpec { - override func spec() { describe("PDFPagiationStyle") { - context("default") { - let style = PDFPaginationStyle.default it("can format a page number") { @@ -26,7 +23,6 @@ class PDFPaginationStyle_Spec: QuickSpec { } context("roman") { - let style = PDFPaginationStyle.roman(template: "%@ / %@") it("can format a page number") { @@ -35,7 +31,6 @@ class PDFPaginationStyle_Spec: QuickSpec { } context("customNumberFormat") { - let formatter = NumberFormatter() formatter.minimumFractionDigits = 2 @@ -48,9 +43,8 @@ class PDFPaginationStyle_Spec: QuickSpec { } context("customClosure") { - - let style = PDFPaginationStyle.customClosure { (page, total) -> String in - return String(format: "%i - %i", page * page, 2 * total) + let style = PDFPaginationStyle.customClosure { page, total -> String in + String(format: "%i - %i", page * page, 2 * total) } it("can format a page number") { @@ -59,7 +53,6 @@ class PDFPaginationStyle_Spec: QuickSpec { } context("equatable") { - it("can be equated when default") { expect(PDFPaginationStyle.default == PDFPaginationStyle.default).to(beTrue()) } @@ -78,30 +71,29 @@ class PDFPaginationStyle_Spec: QuickSpec { expect( PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter1) == PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter1) - ).to(beTrue()) + ).to(beTrue()) expect( PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter1) == PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter2) - ).to(beFalse()) + ).to(beFalse()) expect( PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter1) == PDFPaginationStyle.customNumberFormat(template: template2, formatter: numberFormatter1) - ).to(beFalse()) + ).to(beFalse()) expect( PDFPaginationStyle.customNumberFormat(template: template1, formatter: numberFormatter1) == PDFPaginationStyle.customNumberFormat(template: template2, formatter: numberFormatter2) - ).to(beFalse()) + ).to(beFalse()) } it("can be equated when default") { - expect(PDFPaginationStyle.customClosure { (page, total) -> String in - return String(format: "%@ %@", page, total) - } == PDFPaginationStyle.customClosure { (page, total) -> String in - return String(format: "%@ %@", page, total) + expect(PDFPaginationStyle.customClosure { page, total -> String in + String(format: "%@ %@", page, total) + } == PDFPaginationStyle.customClosure { page, total -> String in + String(format: "%@ %@", page, total) }).to(beFalse()) } } } } - } diff --git a/Tests/TPPDFTests/Pagination/PDFPagination_Closure_Spec.swift b/Tests/TPPDFTests/Pagination/PDFPagination_Closure_Spec.swift index f3813442..63d13572 100644 --- a/Tests/TPPDFTests/Pagination/PDFPagination_Closure_Spec.swift +++ b/Tests/TPPDFTests/Pagination/PDFPagination_Closure_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFPagination_Closure_Spec: QuickSpec { - override func spec() { describe("PDFPagination") { - context("Closure") { - it("should have a closure typealias") { // TODO: complete this // let closure: PDFPaginationClosure = { (page: Int, total: Int) -> String in @@ -26,5 +23,4 @@ class PDFPagination_Closure_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Pagination/PDFPagination_Equatable_Spec.swift b/Tests/TPPDFTests/Pagination/PDFPagination_Equatable_Spec.swift index d0af2095..cab5621d 100644 --- a/Tests/TPPDFTests/Pagination/PDFPagination_Equatable_Spec.swift +++ b/Tests/TPPDFTests/Pagination/PDFPagination_Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFPagination_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFPagination") { - context("Equatable") { - it("can be equated") { let pagination = PDFPagination() @@ -40,5 +37,4 @@ class PDFPagination_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Pagination/PDFPagination_Spec.swift b/Tests/TPPDFTests/Pagination/PDFPagination_Spec.swift index b1a810a8..84f2c996 100644 --- a/Tests/TPPDFTests/Pagination/PDFPagination_Spec.swift +++ b/Tests/TPPDFTests/Pagination/PDFPagination_Spec.swift @@ -6,15 +6,13 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFPagination_Spec: QuickSpec { - override func spec() { describe("PDFPagination") { - var pagination: PDFPagination! beforeEach { @@ -22,7 +20,6 @@ class PDFPagination_Spec: QuickSpec { } context("default variables") { - it("should have a default container") { expect(pagination.container) == PDFContainer.none } @@ -42,5 +39,4 @@ class PDFPagination_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTable+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTable+Equatable_Spec.swift index 3e8fb8c3..7d865504 100644 --- a/Tests/TPPDFTests/Table/PDFTable+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTable+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTable_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTable") { - context("Equatable") { - var table: PDFTable! beforeEach { @@ -69,5 +66,4 @@ class PDFTable_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCell+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCell+Equatable_Spec.swift index ec38b27f..cfbb0f69 100644 --- a/Tests/TPPDFTests/Table/PDFTableCell+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCell+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCell_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableCell") { - context("Equatable") { - let cell = PDFTableCell() it("is equal") { @@ -42,5 +39,4 @@ class PDFTableCell_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellAlignment_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellAlignment_Spec.swift index 28ebc72b..cced14b9 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellAlignment_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellAlignment_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellAlignment_Spec: QuickSpec { - override func spec() { describe("PDFTableCellAlignment") { - context("enum values") { - it("has topLeft") { expect(PDFTableCellAlignment.topLeft).toNot(beNil()) } @@ -111,5 +108,4 @@ class PDFTableCellAlignment_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellBorders+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellBorders+Equatable_Spec.swift index 6a7bd466..626e1235 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellBorders+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellBorders+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellBorders_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableCellBorders") { - context("Equatable") { - let style = PDFLineStyle(type: .dotted, color: .orange, width: 10) let borders = PDFTableCellBorders() @@ -47,5 +44,4 @@ class PDFTableCellBorders_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellBorders_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellBorders_Spec.swift index b01a40b3..38d0457b 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellBorders_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellBorders_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellBorders_Spec: QuickSpec { - override func spec() { describe("PDFTableCellBorders") { - context("variables") { - let borders = PDFTableCellBorders() it("has default left border") { @@ -37,7 +34,6 @@ class PDFTableCellBorders_Spec: QuickSpec { } context("initializer") { - it("can be initialized with a left border") { let style = PDFLineStyle(type: .dotted, color: .orange, width: 10) let borders = PDFTableCellBorders(left: style) @@ -68,5 +64,4 @@ class PDFTableCellBorders_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellPosition+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellPosition+Equatable_Spec.swift index 534436cc..6ed78ed0 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellPosition+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellPosition+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellPosition_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableCellPosition") { - context("Equatable") { - let position = PDFTableCellPosition(row: 1, column: 2) it("is equal") { @@ -36,5 +33,4 @@ class PDFTableCellPosition_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellPosition_Hashable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellPosition_Hashable_Spec.swift index 41553778..5b7406b5 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellPosition_Hashable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellPosition_Hashable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellPosition_Hashable_Spec: QuickSpec { - override func spec() { describe("PDFTableCellPosition") { - context("Hashable") { - it("can create a hashvalue") { let position1 = PDFTableCellPosition(row: 1, column: 2) let position2 = PDFTableCellPosition(row: 4, column: 9) @@ -26,5 +23,4 @@ class PDFTableCellPosition_Hashable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellPosition_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellPosition_Spec.swift index 6ff96eee..96915899 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellPosition_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellPosition_Spec.swift @@ -6,21 +6,18 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellPosition_Spec: QuickSpec { - override func spec() { describe("PDFTableCellPosition") { - let row = 2 let column = 5 let position = PDFTableCellPosition(row: row, column: column) context("variables") { - it("has a row") { expect(position.row).toNot(beNil()) } @@ -31,7 +28,6 @@ class PDFTableCellPosition_Spec: QuickSpec { } context("initializer") { - it("can be initialized with a row and a column") { expect(position.row) == row expect(position.column) == column @@ -39,5 +35,4 @@ class PDFTableCellPosition_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellStyle+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellStyle+Equatable_Spec.swift index 655852a5..eb1fbe47 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellStyle+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellStyle+Equatable_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellStyle_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableCellStyle") { - context("Equatable") { - let style = PDFTableCellStyle() it("is equal") { @@ -45,5 +41,4 @@ class PDFTableCellStyle_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCellStyle_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCellStyle_Spec.swift index 9a29e66c..a8eb5765 100644 --- a/Tests/TPPDFTests/Table/PDFTableCellStyle_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCellStyle_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCellStyle_Spec: QuickSpec { - override func spec() { describe("PDFTableCellStyle") { - context("variables") { - let style = PDFTableCellStyle() it("has default colors") { @@ -35,7 +31,6 @@ class PDFTableCellStyle_Spec: QuickSpec { } context("initializer") { - it("can be initialized with colors") { let colors = (fill: Color.orange, text: Color.green) let cell = PDFTableCellStyle(colors: colors) @@ -60,5 +55,4 @@ class PDFTableCellStyle_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableCell_Spec.swift b/Tests/TPPDFTests/Table/PDFTableCell_Spec.swift index f876bb07..248a1ce8 100644 --- a/Tests/TPPDFTests/Table/PDFTableCell_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableCell_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableCell_Spec: QuickSpec { - override func spec() { describe("PDFTableCell") { - context("variables") { - let cell = PDFTableCell() it("has an optional content") { @@ -34,7 +30,6 @@ class PDFTableCell_Spec: QuickSpec { } context("initializer") { - it("can be initialized with a content") { let content = try! PDFTableContent(content: "EXAMPLE") let cell = PDFTableCell(content: content) @@ -58,5 +53,4 @@ class PDFTableCell_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableContent+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableContent+Equatable_Spec.swift index 35d6e174..2dbf0633 100644 --- a/Tests/TPPDFTests/Table/PDFTableContent+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableContent+Equatable_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableContent_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableContent") { - context("Equatable") { - var content: PDFTableContent! beforeEach { @@ -54,8 +51,8 @@ class PDFTableContent_Equatable_Spec: QuickSpec { content.content = Image() let base64Data = """ -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 + """ let data = Data(base64Encoded: base64Data)! let otherContent = PDFTableContent(type: .image, content: Image(data: data)!) expect(content) != otherContent @@ -85,5 +82,4 @@ iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAA } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableContent_Spec.swift b/Tests/TPPDFTests/Table/PDFTableContent_Spec.swift index c6b065b2..9d09197c 100644 --- a/Tests/TPPDFTests/Table/PDFTableContent_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableContent_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableContent_Spec: QuickSpec { - override func spec() { describe("PDFTableContent") { - context("enum ContentType") { - it("has a value none") { expect(PDFTableContent.ContentType.none).toNot(beNil()) } @@ -36,7 +33,6 @@ class PDFTableContent_Spec: QuickSpec { } context("variables") { - it("has a default type") { expect((try? PDFTableContent(content: nil))?.type) == PDFTableContent.ContentType.none } @@ -49,14 +45,13 @@ class PDFTableContent_Spec: QuickSpec { } context("initializer") { - it("can be initialized with any") { expect { try PDFTableContent(content: 123) - }.toNot(throwError()) + }.toNot(throwError()) expect { try PDFTableContent(content: ["EXAMPLE"]) - }.to(throwError()) + }.to(throwError()) } it("can be initialized with type and optional content") { @@ -68,7 +63,6 @@ class PDFTableContent_Spec: QuickSpec { } context("content") { - var content: PDFTableContent! beforeEach { @@ -78,7 +72,7 @@ class PDFTableContent_Spec: QuickSpec { it("can set to nil") { expect { try content.setContent(content: nil) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.none)) expect(content.content).toEventually(beNil()) } @@ -88,7 +82,7 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: "EXAMPLE") - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.string)) expect(content.content as? String).toEventually(equal("EXAMPLE")) } @@ -98,7 +92,7 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: value) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.image)) expect(content.content as? Image).toEventually(equal(value)) } @@ -108,17 +102,17 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: value) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.attributedString)) expect(content.content as? NSAttributedString).toEventually(equal(value)) } it("can set to int") { - let value = 123456 + let value = 123_456 expect { try content.setContent(content: value) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.string)) expect(content.content as? String).toEventually(equal("123456")) } @@ -128,7 +122,7 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: value) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.string)) expect(content.content as? String).toEventually(equal("123.456")) } @@ -138,7 +132,7 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: value) - }.toNot(throwError()) + }.toNot(throwError()) expect(content.type).toEventually(equal(PDFTableContent.ContentType.string)) expect(content.content as? String).toEventually(equal("123.456")) } @@ -148,12 +142,11 @@ class PDFTableContent_Spec: QuickSpec { expect { try content.setContent(content: value) - }.to(throwError()) + }.to(throwError()) } } context("computed variables") { - var content: PDFTableContent! beforeEach { @@ -249,9 +242,7 @@ class PDFTableContent_Spec: QuickSpec { } context("extensions") { - context("String") { - it("can be converted to content") { let value = "EXAMPLE" let content = value.asTableContent @@ -261,7 +252,6 @@ class PDFTableContent_Spec: QuickSpec { } context("NSAttributedString") { - it("can be converted to content") { let attributedString = NSAttributedString(string: "EXAMPLE") let content = attributedString.asTableContent @@ -271,7 +261,6 @@ class PDFTableContent_Spec: QuickSpec { } context("Image") { - it("can be converted to content") { let image = Image() let content = image.asTableContent @@ -282,5 +271,4 @@ class PDFTableContent_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableStyle+Defaults_Spec.swift b/Tests/TPPDFTests/Table/PDFTableStyle+Defaults_Spec.swift index 6ff1756f..55bd8f24 100644 --- a/Tests/TPPDFTests/Table/PDFTableStyle+Defaults_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableStyle+Defaults_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableStyle_Defaults_Spec: QuickSpec { - override func spec() { describe("PDFTableStyle") { - context("Defaults") { - it("has a simple style") { let darkGray = Color(red: 59.0 / 255.0, green: 59.0 / 255.0, blue: 59.0 / 255.0, alpha: 1.0) @@ -65,5 +61,4 @@ class PDFTableStyle_Defaults_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableStyle+Equatable_Spec.swift b/Tests/TPPDFTests/Table/PDFTableStyle+Equatable_Spec.swift index 09add3c3..0bd53703 100644 --- a/Tests/TPPDFTests/Table/PDFTableStyle+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableStyle+Equatable_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableStyle_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFTableStyle") { - context("Equatable") { - let style = PDFTableStyle(rowHeaderCount: 1, columnHeaderCount: 2, footerCount: 3, @@ -30,14 +26,14 @@ class PDFTableStyle_Equatable_Spec: QuickSpec { it("is equal") { let otherStyle = PDFTableStyle(rowHeaderCount: 1, - columnHeaderCount: 2, - footerCount: 3, - outline: PDFLineStyle.none, - rowHeaderStyle: PDFTableCellStyle(), - columnHeaderStyle: PDFTableCellStyle(), - footerStyle: PDFTableCellStyle(), - contentStyle: PDFTableCellStyle(), - alternatingContentStyle: PDFTableCellStyle()) + columnHeaderCount: 2, + footerCount: 3, + outline: PDFLineStyle.none, + rowHeaderStyle: PDFTableCellStyle(), + columnHeaderStyle: PDFTableCellStyle(), + footerStyle: PDFTableCellStyle(), + contentStyle: PDFTableCellStyle(), + alternatingContentStyle: PDFTableCellStyle()) expect(style) == otherStyle } @@ -178,5 +174,4 @@ class PDFTableStyle_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableStyle_Spec.swift b/Tests/TPPDFTests/Table/PDFTableStyle_Spec.swift index 22a87500..a12597df 100644 --- a/Tests/TPPDFTests/Table/PDFTableStyle_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableStyle_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableStyle_Spec: QuickSpec { - override func spec() { describe("PDFTableStyle") { - context("variables") { - let style = PDFTableStyle() it("has a row header count") { @@ -58,7 +54,6 @@ class PDFTableStyle_Spec: QuickSpec { } context("initializer") { - it("can be initialized with default values") { let style = PDFTableStyle() @@ -168,5 +163,4 @@ class PDFTableStyle_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTableValidator_Spec.swift b/Tests/TPPDFTests/Table/PDFTableValidator_Spec.swift index 314bf60a..261ab6c2 100644 --- a/Tests/TPPDFTests/Table/PDFTableValidator_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTableValidator_Spec.swift @@ -7,48 +7,46 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFTableValidator_Spec: QuickSpec { - override func spec() { describe("PDFTableValidator") { - let data = [ [ "1|1", "1|2", "1|3", - "1|4" + "1|4", ], [ "2|1", "2|2", "2|3", - "2|4" - ] + "2|4", + ], ] let alignments = [ [ PDFTableCellAlignment.left, PDFTableCellAlignment.top, PDFTableCellAlignment.right, - PDFTableCellAlignment.bottom + PDFTableCellAlignment.bottom, ], [ PDFTableCellAlignment.topLeft, PDFTableCellAlignment.topRight, PDFTableCellAlignment.bottomRight, - PDFTableCellAlignment.bottomLeft - ] + PDFTableCellAlignment.bottomLeft, + ], ] let widths: [CGFloat] = [ 0.1, 0.2, 0.3, - 0.4 + 0.4, ] var table: PDFTable! @@ -58,7 +56,6 @@ class PDFTableValidator_Spec: QuickSpec { } context("table validation") { - it("should succeed when no cells in table") { expect { try PDFTableValidator.validateTable(table: table) @@ -67,10 +64,10 @@ class PDFTableValidator_Spec: QuickSpec { it("fails when not same amount of data than widths") { #if arch(x86_64) - table.widths = widths - expect { - table.content = [["1", "2"]] - }.to(throwAssertion()) + table.widths = widths + expect { + table.content = [["1", "2"]] + }.to(throwAssertion()) #endif } @@ -81,43 +78,41 @@ class PDFTableValidator_Spec: QuickSpec { expect { try PDFTableValidator.validateTable(table: table) - }.toNot(throwError()) + }.toNot(throwError()) } } context("data validation") { - it("fails when no data given") { expect { try PDFTableValidator.validateTableData(data: []) - }.to(throwError(PDFError.tableIsEmpty)) + }.to(throwError(PDFError.tableIsEmpty)) } it("fails when alignments not given and count not same") { expect { try PDFTableValidator.validateTableData(data: data, alignments: []) - }.to(throwError( - PDFError.tableStructureInvalid(message: "Data and alignment must be equal size!") - )) + }.to(throwError( + PDFError.tableStructureInvalid(message: "Data and alignment must be equal size!") + )) } it("fails when data row and alignment row is not the same") { expect { try PDFTableValidator.validateTableData(data: data, alignments: [[], []]) - }.to(throwError( - PDFError.tableStructureInvalid(message: "Data and alignment for row with index 0 does not have the same amount!") - )) + }.to(throwError( + PDFError.tableStructureInvalid(message: "Data and alignment for row with index 0 does not have the same amount!") + )) } it("fails when data row and column widths count is not the same") { expect { try PDFTableValidator.validateTableData(data: data, alignments: nil, columnWidths: []) - }.to(throwError( - PDFError.tableStructureInvalid(message: "Data and alignment for row with index 0 does not have the same amount!") - )) + }.to(throwError( + PDFError.tableStructureInvalid(message: "Data and alignment for row with index 0 does not have the same amount!") + )) } } } } - } diff --git a/Tests/TPPDFTests/Table/PDFTable_Spec.swift b/Tests/TPPDFTests/Table/PDFTable_Spec.swift index cf3380e9..cf0e643e 100644 --- a/Tests/TPPDFTests/Table/PDFTable_Spec.swift +++ b/Tests/TPPDFTests/Table/PDFTable_Spec.swift @@ -6,18 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // - -import Quick import Nimble +import Quick @testable import TPPDF class PDFTable_Spec: QuickSpec { - override func spec() { describe("PDFTable") { - context("variables") { - let table = PDFTable(rows: 0, columns: 0) it("has a default style") { @@ -46,7 +42,6 @@ class PDFTable_Spec: QuickSpec { } context("cell style") { - it("can set style of cell") { let table = PDFTable(rows: 0, columns: 0) table.cells = [[PDFTableCell()]] @@ -55,10 +50,8 @@ class PDFTable_Spec: QuickSpec { table[0, 0].style = style expect(table.cells[0][0].style).toEventually(equal(style)) - } } } } - } diff --git a/Tests/TPPDFTests/Text/PDFAttributedText+Equatable_Spec.swift b/Tests/TPPDFTests/Text/PDFAttributedText+Equatable_Spec.swift index 2d418507..b92c1477 100644 --- a/Tests/TPPDFTests/Text/PDFAttributedText+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFAttributedText+Equatable_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFAttributedText_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFAttributedText") { - context("Equatable") { - let text = PDFAttributedText(text: NSAttributedString(string: "EXAMPLE")) it("is equal") { @@ -32,5 +29,4 @@ class PDFAttributedText_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFAttributedTextObject_Spec.swift b/Tests/TPPDFTests/Text/PDFAttributedTextObject_Spec.swift index 8d0c499a..201474c4 100644 --- a/Tests/TPPDFTests/Text/PDFAttributedTextObject_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFAttributedTextObject_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFAttributedTextObject_Spec: QuickSpec { - override func spec() { describe("PDFAttributedTextObject") { - describe("initializer") { - let simpleText = "example" it("can be initialized with a simple object") { @@ -43,12 +40,11 @@ class PDFAttributedTextObject_Spec: QuickSpec { let custom = CustomTextObject() expect { - let _ = PDFAttributedTextObject(text: custom) - }.to(throwAssertion()) + _ = PDFAttributedTextObject(text: custom) + }.to(throwAssertion()) #endif } } } } - } diff --git a/Tests/TPPDFTests/Text/PDFAttributedText_Spec.swift b/Tests/TPPDFTests/Text/PDFAttributedText_Spec.swift index 0fc3cdb3..517b595d 100644 --- a/Tests/TPPDFTests/Text/PDFAttributedText_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFAttributedText_Spec.swift @@ -7,15 +7,13 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFAttributedText_Spec: QuickSpec { - override func spec() { describe("PDFAttributedText") { - it("can be initialized with an attributed string") { let attributed = NSAttributedString(string: "example") let textObject = PDFAttributedText(text: attributed) @@ -24,5 +22,4 @@ class PDFAttributedText_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFFontObject_Spec.swift b/Tests/TPPDFTests/Text/PDFFontObject_Spec.swift index 97d6edfb..ff1594ac 100644 --- a/Tests/TPPDFTests/Text/PDFFontObject_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFFontObject_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFFontObject_Spec: QuickSpec { - override func spec() { describe("PDFFontObject") { - let font = Font.boldSystemFont(ofSize: 100) var object: PDFFontObject! @@ -24,14 +22,12 @@ class PDFFontObject_Spec: QuickSpec { } context("variables") { - it("has a font instance") { expect(object.font) == font } } describe("calculation") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! @@ -46,7 +42,7 @@ class PDFFontObject_Spec: QuickSpec { it("can set text color") { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.fonts[container]).toEventually(equal(font)) expect(object.frame) == CGRect.null @@ -58,5 +54,4 @@ class PDFFontObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFSimpleText+Equatable_Spec.swift b/Tests/TPPDFTests/Text/PDFSimpleText+Equatable_Spec.swift index 56f2d8bc..936992c8 100644 --- a/Tests/TPPDFTests/Text/PDFSimpleText+Equatable_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFSimpleText+Equatable_Spec.swift @@ -6,17 +6,14 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFSimpleText_Equatable_Spec: QuickSpec { - override func spec() { describe("PDFSimpleText") { - context("Equatable") { - let text = PDFSimpleText(text: "EXAMPLE") it("is equal") { @@ -36,5 +33,4 @@ class PDFSimpleText_Equatable_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFSimpleText_Spec.swift b/Tests/TPPDFTests/Text/PDFSimpleText_Spec.swift index 6444e44f..67606d96 100644 --- a/Tests/TPPDFTests/Text/PDFSimpleText_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFSimpleText_Spec.swift @@ -7,17 +7,15 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFSimpleText_Spec: QuickSpec { - override func spec() { describe("PDFSimpleText") { - let simpleText = "EXAMPLE" - let spacing: CGFloat = 10.0 + let spacing: CGFloat = 10.0 var textObject: PDFSimpleText! beforeEach { @@ -25,7 +23,6 @@ class PDFSimpleText_Spec: QuickSpec { } context("variables") { - it("has a text instance") { expect(textObject.text) == simpleText } @@ -45,5 +42,4 @@ class PDFSimpleText_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFTextColorObject_Spec.swift b/Tests/TPPDFTests/Text/PDFTextColorObject_Spec.swift index c409a0bd..fa5bb4ee 100644 --- a/Tests/TPPDFTests/Text/PDFTextColorObject_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFTextColorObject_Spec.swift @@ -7,15 +7,13 @@ // import CoreGraphics -import Quick import Nimble +import Quick @testable import TPPDF class PDFTextColorObject_Spec: QuickSpec { - override func spec() { describe("PDFTextColorObject") { - let color = Color.red var object: PDFTextColorObject! @@ -24,14 +22,12 @@ class PDFTextColorObject_Spec: QuickSpec { } context("variables") { - it("has a color instance") { expect(object.color) == color } } describe("calculation") { - let document = PDFDocument(format: .a4) var generator: PDFGenerator! @@ -46,7 +42,7 @@ class PDFTextColorObject_Spec: QuickSpec { it("can set text color") { expect { result = try object.calculate(generator: generator, container: container) - }.toNot(throwError()) + }.toNot(throwError()) expect(generator.textColor[container]).toEventually(equal(color)) expect(object.frame) == CGRect.null @@ -58,5 +54,4 @@ class PDFTextColorObject_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Text/PDFText_Spec.swift b/Tests/TPPDFTests/Text/PDFText_Spec.swift index aa89e082..ad2cd468 100644 --- a/Tests/TPPDFTests/Text/PDFText_Spec.swift +++ b/Tests/TPPDFTests/Text/PDFText_Spec.swift @@ -7,17 +7,14 @@ // import Foundation -import Quick import Nimble +import Quick @testable import TPPDF class PDFText_Spec: QuickSpec { - override func spec() { describe("PDFSimpleText") { - context("Equatable") { - it("is equal if both simple text") { let text: PDFText = PDFSimpleText(text: "EXAMPLE") let otherText: PDFText = PDFSimpleText(text: "EXAMPLE") @@ -43,5 +40,4 @@ class PDFText_Spec: QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Utils/PDFCalculations_Spec.swift b/Tests/TPPDFTests/Utils/PDFCalculations_Spec.swift index 4091a1d5..f222f44f 100644 --- a/Tests/TPPDFTests/Utils/PDFCalculations_Spec.swift +++ b/Tests/TPPDFTests/Utils/PDFCalculations_Spec.swift @@ -8,17 +8,14 @@ import CoreGraphics import Foundation -import Quick import Nimble +import Quick @testable import TPPDF -class PDFCalculations_Spec : QuickSpec { - +class PDFCalculations_Spec: QuickSpec { override func spec() { describe("PDFCalculations") { - context("calculate text frame and remainder") { - it("should return correct frame and remainder") { let attributedString = NSAttributedString(string: "12345\n12345\n12345\n12345\n12345") @@ -57,5 +54,4 @@ class PDFCalculations_Spec : QuickSpec { } } } - } diff --git a/Tests/TPPDFTests/Utils/PDFError_Spec.swift b/Tests/TPPDFTests/Utils/PDFError_Spec.swift index 4476c87d..a1475358 100644 --- a/Tests/TPPDFTests/Utils/PDFError_Spec.swift +++ b/Tests/TPPDFTests/Utils/PDFError_Spec.swift @@ -6,28 +6,22 @@ // Copyright © 2017 CocoaPods. All rights reserved. // -import Quick import Nimble +import Quick @testable import TPPDF class PDFError_Spec: QuickSpec { - override func spec() { describe("PDFError") { - it("should have enum values") { expect(PDFError.tableContentInvalid(value: nil)).toNot(beNil()) expect(PDFError.tableIsEmpty).toNot(beNil()) expect(PDFError.tableStructureInvalid(message: "MESSAGE")).toNot(beNil()) expect(PDFError.tableIndexOutOfBounds(index: 5, length: 4)).toNot(beNil()) - expect(PDFError.tableCellWeakReferenceBroken).toNot(beNil()) expect(PDFError.textObjectIsNil).toNot(beNil()) expect(PDFError.textObjectNotCalculated).toNot(beNil()) - - expect(PDFError.invalidHexLength(length: 7)).toNot(beNil()) - expect(PDFError.invalidHex(hex: "ABCD")).toNot(beNil()) } it("should have a localized description") { @@ -36,15 +30,10 @@ class PDFError_Spec: QuickSpec { expect(PDFError.tableIsEmpty.localizedDescription) == "Table is empty" expect(PDFError.tableStructureInvalid(message: "MESSAGE").localizedDescription) == "Table structure invalid: MESSAGE" expect(PDFError.tableIndexOutOfBounds(index: 5, length: 4).localizedDescription) == "Table index out of bounds: " - expect(PDFError.tableCellWeakReferenceBroken.localizedDescription) == "Weak reference in table cell is broken" expect(PDFError.textObjectIsNil.localizedDescription) == "No text object has been set" expect(PDFError.textObjectNotCalculated.localizedDescription) == "Text object is missing string, maybe not calculated?" - - expect(PDFError.invalidHexLength(length: 7).localizedDescription) == "Hex color string has invalid length: 7" - expect(PDFError.invalidHex(hex: "ABCD").localizedDescription) == "Invalid hexdecimal string: ABCD" } } } - } diff --git a/Tests/TPPDFTests/Utils/PDFObject_Spec.swift b/Tests/TPPDFTests/Utils/PDFObject_Spec.swift index 4d764309..18d85373 100644 --- a/Tests/TPPDFTests/Utils/PDFObject_Spec.swift +++ b/Tests/TPPDFTests/Utils/PDFObject_Spec.swift @@ -5,18 +5,15 @@ // Created by Philip Niedertscheider on 02/11/2017. // -import Foundation import CoreGraphics -import Quick +import Foundation import Nimble +import Quick @testable import TPPDF class PDFObject_Spec: QuickSpec { - override func spec() { - describe("PDFObject") { - let object = PDFRenderObject() it("should have a null frame as default") { @@ -55,5 +52,4 @@ class PDFObject_Spec: QuickSpec { } } } - }