     
     
     /// return attributed string for header/footer
-    private func headerFooter(primaryString: String?, primaryAlignment: AlignmentType, secondaryString: String?, secondaryAlignment: AlignmentType) -> NSAttributedString {
-        
+    private func headerFooter(for location: HeaderFooterLocation) -> NSAttributedString {
+        
+        let keys = location.keys
+        
+        guard
+            let settings = NSPrintOperation.current?.printInfo.dictionary() as? [NSPrintInfo.AttributeKey: Any],
+            (settings[keys.needsDraw] as? Bool) ?? false
+            else { return NSAttributedString() }
+        
+        let primaryInfoType = PrintInfoType(settings[keys.primaryContent] as? Int)
+        let primaryAlignment = AlignmentType(settings[keys.primaryAlignment] as? Int)
+        let secondaryInfoType = PrintInfoType(settings[keys.secondaryContent] as? Int)
+        let secondaryAlignment = AlignmentType(settings[keys.secondaryAlignment] as? Int)
+        
+        let primaryString = self.printInfoString(type: primaryInfoType)
+        let secondaryString = self.printInfoString(type: secondaryInfoType)
+        
+        switch (primaryString, secondaryString) {
         // case: empty
-        guard primaryString != nil || secondaryString != nil else { return NSAttributedString() }
-        
+        case (nil, nil):
+            return NSAttributedString()
+            
         // case: single content
-        if let string = primaryString, secondaryString == nil {
+        case let (.some(string), nil):
             return NSAttributedString(string: string, attributes: self.headerFooterAttributes(for: primaryAlignment))
-        }
-        if let string = secondaryString, primaryString == nil {
+        case let (nil, .some(string)):
             return NSAttributedString(string: string, attributes: self.headerFooterAttributes(for: secondaryAlignment))
-        }
-        guard let primaryString = primaryString, let secondaryString = secondaryString else { fatalError() }
-        
-        // case: double-sided
-        if primaryAlignment == .left, secondaryAlignment == .right {
-            return NSAttributedString(string: primaryString + "\t\t" + secondaryString, attributes: self.headerFooterAttributes(for: .left))
-        }
-        if primaryAlignment == .right, secondaryAlignment == .left {
-            return NSAttributedString(string: secondaryString + "\t\t" + primaryString, attributes: self.headerFooterAttributes(for: .left))
-        }
-        
-        // case: two lines
-        let primaryAttrString = NSAttributedString(string: primaryString, attributes: self.headerFooterAttributes(for: primaryAlignment))
-        let secondaryAttrString = NSAttributedString(string: secondaryString, attributes: self.headerFooterAttributes(for: secondaryAlignment))
-        
-        return primaryAttrString + NSAttributedString(string: "\n") + secondaryAttrString
+            
+        case let (.some(primaryString), .some(secondaryString)):
+            switch (primaryAlignment, secondaryAlignment) {
+            // case: double-sided
+            case (.left, .right):
+                return NSAttributedString(string: primaryString + "\t\t" + secondaryString, attributes: self.headerFooterAttributes(for: .left))
+            case (.right, .left):
+                return NSAttributedString(string: secondaryString + "\t\t" + primaryString, attributes: self.headerFooterAttributes(for: .left))
+                
+            // case: two lines
+            default:
+                let primaryAttrString = NSAttributedString(string: primaryString, attributes: self.headerFooterAttributes(for: primaryAlignment))
+                let secondaryAttrString = NSAttributedString(string: secondaryString, attributes: self.headerFooterAttributes(for: secondaryAlignment))
+                
+                return primaryAttrString + NSAttributedString(string: "\n") + secondaryAttrString
+            }
+        }
     }
     
     

            
        case .none:
            return nil
        }
    }
    

    /// return page header attributed string
    override var pageHeader: NSAttributedString {
        
        return self.headerFooter(for: .header)
    }
    
    
    /// return page footer attributed string
    override var pageFooter: NSAttributedString {
        
        return self.headerFooter(for: .footer)
    }
    
    
