diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 3286132b9..b10eb193b 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -273,11 +273,14 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0710; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = FolioReader; TargetAttributes = { 1A42C2881C0E3882000F2137 = { CreatedOnToolsVersion = 7.1.1; + DevelopmentTeam = 32F2T8EJ6G; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.BackgroundModes = { enabled = 1; @@ -286,10 +289,15 @@ }; CA10C1301C572A4B0049165D = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = 32F2T8EJ6G; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; TestTargetID = 1A42C2881C0E3882000F2137; }; D12066621D65FABD006E1D18 = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = 32F2T8EJ6G; + ProvisioningStyle = Automatic; }; }; }; @@ -665,8 +673,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -710,8 +720,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -730,7 +742,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -740,11 +752,15 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5C8EADB52E1D834750CD7D23 /* Pods-Example.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.Example; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -752,11 +768,15 @@ isa = XCBuildConfiguration; baseConfigurationReference = F4CBB0C2C0FDFA3E1648DB43 /* Pods-Example.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.Example; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; }; name = Release; }; @@ -764,12 +784,16 @@ isa = XCBuildConfiguration; baseConfigurationReference = 3CE90B4095B5C7E6237EEBDD /* Pods-FolioReaderTests.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = FolioReaderTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Debug; @@ -778,12 +802,16 @@ isa = XCBuildConfiguration; baseConfigurationReference = 8E1BE6465444C567F5D1B8E6 /* Pods-FolioReaderTests.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = FolioReaderTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 2.3; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Release; @@ -792,8 +820,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = D7C82C879F323C6E960F882B /* Pods-StoryboardExample.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = StoryboardExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -806,8 +837,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 1D4790507F22E69298DC06E1 /* Pods-StoryboardExample.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = 32F2T8EJ6G; INFOPLIST_FILE = StoryboardExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme index 42724eee5..d78b6713e 100644 --- a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme @@ -1,6 +1,6 @@ 3.0) - MenuItemKit (= 1.1.3) - RealmSwift (~> 1.0) - SSZipArchive (= 1.5) - ZFDragableModalTransition (~> 0.6) - - FontBlaster (2.1.4) - JSQWebViewController (3.0.0) - MenuItemKit (1.1.3) - Nimble (4.1.0) @@ -32,8 +30,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: AEXML: 716fb0a8decba4a3517324a71fee3685b30233d2 - FolioReaderKit: a8f6f5aa4f8c2488e42bff609ae10e3cb31c348e - FontBlaster: b780f709b8f705638d0c80a1ecdfb23b3077d0a6 + FolioReaderKit: 16cbbf673d457016e80ec6230090e70059d3e144 JSQWebViewController: eaa6bd68d9e1426ae25ade99c9bbde4c6cdd4120 MenuItemKit: 11c448d9172936ee79ebb78f36dffd396020a9e5 Nimble: 97a0a4cae5124c117115634b2d055d8c97d0af19 @@ -43,6 +40,6 @@ SPEC CHECKSUMS: SSZipArchive: 29daace2bccb90a47de2837744da397728ff9207 ZFDragableModalTransition: 0d294eaaba6edfcb9839595de765f9ca06a4b524 -PODFILE CHECKSUM: 617d506c4ff6fef0fcf4032d9acdc7ee8ad208e9 +PODFILE CHECKSUM: 55962a6106e53da04861e4602fc98856987b97b3 COCOAPODS: 1.0.1 diff --git a/FolioReaderKit.podspec b/FolioReaderKit.podspec index 54bcba242..35f1a4a1c 100644 --- a/FolioReaderKit.podspec +++ b/FolioReaderKit.podspec @@ -35,7 +35,6 @@ Pod::Spec.new do |s| s.dependency 'MenuItemKit', '1.1.3' s.dependency 'ZFDragableModalTransition', '~> 0.6' s.dependency 'AEXML', '3.0' - s.dependency 'FontBlaster', '2.1.4' s.dependency 'JSQWebViewController', '~> 3.0' s.dependency 'RealmSwift', '~> 1.0' # s.dependency 'SMSegmentView' diff --git a/Source/EPUBCore/FREpubParser.swift b/Source/EPUBCore/FREpubParser.swift index 1ac88baac..612e94d3e 100755 --- a/Source/EPUBCore/FREpubParser.swift +++ b/Source/EPUBCore/FREpubParser.swift @@ -236,9 +236,9 @@ class FREpubParser: NSObject, SSZipArchiveDelegate { let tocData = try NSData(contentsOfFile: tocPath, options: .DataReadingMappedAlways) let xmlDoc = try AEXMLDocument(xmlData: tocData) - if let nav = xmlDoc.root["body"]["nav"].first, itemsList = nav["ol"]["li"].all { + if let nav = xmlDoc.root["body"]["nav"].first, let itemsList = nav["ol"]["li"].all { tocItems = itemsList - } else if let nav = findNavTag(xmlDoc.root["body"]), itemsList = nav["ol"]["li"].all { + } else if let nav = findNavTag(xmlDoc.root["body"]), let itemsList = nav["ol"]["li"].all { tocItems = itemsList } } diff --git a/Source/FolioReaderCenter.swift b/Source/FolioReaderCenter.swift index 7ee2b3641..1b93f0878 100755 --- a/Source/FolioReaderCenter.swift +++ b/Source/FolioReaderCenter.swift @@ -103,6 +103,10 @@ public class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICo enableScrollBetweenChapters(scrollEnabled: true) view.addSubview(collectionView) + if #available(iOS 10.0, *) { + collectionView.prefetchingEnabled = false + } + // Register cell classes collectionView!.registerClass(FolioReaderPage.self, forCellWithReuseIdentifier: reuseIdentifier) diff --git a/Source/FolioReaderContainer.swift b/Source/FolioReaderContainer.swift index 53a3bdddf..e110482f8 100755 --- a/Source/FolioReaderContainer.swift +++ b/Source/FolioReaderContainer.swift @@ -7,7 +7,6 @@ // import UIKit -import FontBlaster var readerConfig: FolioReaderConfig! var book: FRBook! diff --git a/Source/FolioReaderKit.swift b/Source/FolioReaderKit.swift index 87b3f0cd2..11311ee7d 100755 --- a/Source/FolioReaderKit.swift +++ b/Source/FolioReaderKit.swift @@ -179,7 +179,7 @@ public class FolioReader: NSObject { // MARK: - Get Cover Image /** - Read Cover Image and Return an IUImage + Read Cover Image and Return an `UIImage` */ public class func getCoverImage(epubPath: String) -> UIImage? { return FREpubParser().parseCoverImage(epubPath) @@ -606,11 +606,11 @@ internal extension UIImage { CGContextSetBlendMode(context, CGBlendMode.Normal) let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect - CGContextClipToMask(context, rect, self.CGImage) + CGContextClipToMask(context, rect, self.CGImage!) tintColor.setFill() CGContextFillRect(context, rect) - let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage + let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage UIGraphicsEndImageContext() return newImage @@ -633,11 +633,11 @@ internal extension UIImage { UIColor.whiteColor().setFill() } - CGContextFillRect(context, rect) + CGContextFillRect(context!, rect) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return image + return image! } /** @@ -651,7 +651,7 @@ internal extension UIImage { layer.renderInContext(UIGraphicsGetCurrentContext()!) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return img + return img! } /** @@ -665,7 +665,7 @@ internal extension UIImage { view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return img + return img! } } diff --git a/Source/FolioReaderPage.swift b/Source/FolioReaderPage.swift index a61484eba..e12b2205c 100755 --- a/Source/FolioReaderPage.swift +++ b/Source/FolioReaderPage.swift @@ -188,7 +188,7 @@ public class FolioReaderPage: UICollectionViewCell, UIWebViewDelegate, UIGesture shouldShowBar = false - let decoded = url.absoluteString.stringByRemovingPercentEncoding as String! + let decoded = url.absoluteString!.stringByRemovingPercentEncoding as String! let rect = CGRectFromString(decoded.substringFromIndex(decoded.startIndex.advancedBy(12))) webView.createMenu(options: true) @@ -198,7 +198,7 @@ public class FolioReaderPage: UICollectionViewCell, UIWebViewDelegate, UIGesture return false } else if url.scheme == "play-audio" { - let decoded = url.absoluteString.stringByRemovingPercentEncoding as String! + let decoded = url.absoluteString!.stringByRemovingPercentEncoding as String! let playID = decoded.substringFromIndex(decoded.startIndex.advancedBy(13)) let chapter = FolioReader.sharedInstance.readerCenter?.getCurrentChapter() let href = chapter != nil ? chapter!.href : ""; @@ -246,7 +246,7 @@ public class FolioReaderPage: UICollectionViewCell, UIWebViewDelegate, UIGesture } else if url.scheme == "mailto" { print("Email") return true - } else if url.absoluteString != "about:blank" && url.scheme.containsString("http") && navigationType == .LinkClicked { + } else if url.absoluteString != "about:blank" && url.scheme!.containsString("http") && navigationType == .LinkClicked { if #available(iOS 9.0, *) { let safariVC = SFSafariViewController(URL: request.URL!) @@ -263,19 +263,19 @@ public class FolioReaderPage: UICollectionViewCell, UIWebViewDelegate, UIGesture // Check if the url is a custom class based onClick listerner var isClassBasedOnClickListenerScheme = false for listener in readerConfig.classBasedOnClickListeners { - if - url.scheme == listener.schemeName, - let absoluteURLString = request.URL?.absoluteString, - range = absoluteURLString.rangeOfString("/clientX=") { - let baseURL = absoluteURLString.substringToIndex(range.startIndex) - let positionString = absoluteURLString.substringFromIndex(range.startIndex) - if let point = getEventTouchPoint(fromPositionParameterString: positionString) { - let attributeContentString = (baseURL.stringByReplacingOccurrencesOfString("\(url.scheme)://", withString: "").stringByRemovingPercentEncoding) - // Call the on click action block - listener.onClickAction(attributeContent: attributeContentString, touchPointRelativeToWebView: point) - // Mark the scheme as class based click listener scheme - isClassBasedOnClickListenerScheme = true - } + + if url.scheme == listener.schemeName, + let absoluteURLString = request.URL?.absoluteString, + let range = absoluteURLString.rangeOfString("/clientX=") { + let baseURL = absoluteURLString.substringToIndex(range.startIndex) + let positionString = absoluteURLString.substringFromIndex(range.startIndex) + if let point = getEventTouchPoint(fromPositionParameterString: positionString) { + let attributeContentString = (baseURL.stringByReplacingOccurrencesOfString("\(url.scheme)://", withString: "").stringByRemovingPercentEncoding) + // Call the on click action block + listener.onClickAction(attributeContent: attributeContentString, touchPointRelativeToWebView: point) + // Mark the scheme as class based click listener scheme + isClassBasedOnClickListenerScheme = true + } } } diff --git a/Source/FolioReaderPageIndicator.swift b/Source/FolioReaderPageIndicator.swift index 16dabfe3a..0c2c8e5e0 100644 --- a/Source/FolioReaderPageIndicator.swift +++ b/Source/FolioReaderPageIndicator.swift @@ -80,14 +80,6 @@ class FolioReaderPageIndicator: UIView { pagesLabel.textColor = isNight(UIColor(white: 5, alpha: 0.6), UIColor(white: 0, alpha: 0.9)) } - override func animationDidStop(anim: CAAnimation, finished flag: Bool) { - // Set the shadow color to the final value of the animation is done - if let _keyPath = anim.valueForKeyPath("keyPath") as? String where _keyPath == "shadowColor" { - let color = isNight(readerConfig.nightModeBackground, UIColor.whiteColor()) - layer.shadowColor = color.CGColor - } - } - private func reloadViewWithPage(page: Int) { let pagesRemaining = FolioReader.needsRTLChange ? totalPages-(totalPages-page+1) : totalPages-page @@ -110,3 +102,13 @@ class FolioReaderPageIndicator: UIView { reloadView(updateShadow: false) } } + +extension FolioReaderPageIndicator: CAAnimationDelegate { + func animationDidStop(anim: CAAnimation, finished flag: Bool) { + // Set the shadow color to the final value of the animation is done + if let keyPath = anim.valueForKeyPath("keyPath") as? String where keyPath == "shadowColor" { + let color = isNight(readerConfig.nightModeBackground, UIColor.whiteColor()) + layer.shadowColor = color.CGColor + } + } +} diff --git a/Source/FolioReaderWebView.swift b/Source/FolioReaderWebView.swift index 7ff26b794..9c0e76ea8 100644 --- a/Source/FolioReaderWebView.swift +++ b/Source/FolioReaderWebView.swift @@ -30,7 +30,7 @@ public class FolioReaderWebView: UIWebView { || (action == #selector(define(_:)) && isOneWord) || (action == #selector(play(_:)) && (book.hasAudio() || readerConfig.enableTTS)) || (action == #selector(share(_:)) && readerConfig.allowSharing) - || (action == #selector(NSObject.copy(_:)) && readerConfig.allowSharing) { + || (action == #selector(copy(_:)) && readerConfig.allowSharing) { return true } return false diff --git a/Vendor/FontBlaster/FontBlaster.swift b/Vendor/FontBlaster/FontBlaster.swift new file mode 100644 index 000000000..86fc78ce7 --- /dev/null +++ b/Vendor/FontBlaster/FontBlaster.swift @@ -0,0 +1,228 @@ +// +// FontBlaster.swift +// FontBlaster +// +// Created by Arthur Sabintsev on 5/5/15. +// Copyright (c) 2015 Arthur Ariel Sabintsev. All rights reserved. +// + +import Foundation +import CoreGraphics +import CoreText + + +// MARK: - Enums + +/** + Limits the type of fonts that can be loaded into an application + + There are two options: + - TrueTypeFont + - OpenTypeFont + */ +private enum SupportedFontExtensions: String { + case TrueTypeFont = ".ttf" + case OpenTypeFont = ".otf" +} + + +// MARK: - FontBlaster + +/** + The FontBlaster Class. + + Only one class method can be accessed + - blast(_:) + Only one class variable can be accessed and modified + - debugEnabled + */ +final public class FontBlaster { + + private typealias FontPath = String + private typealias FontName = String + private typealias FontExtension = String + private typealias Font = (path: FontPath, name: FontName, ext: FontExtension) + + /** + Used to toggle debug println() statements + */ + public static var debugEnabled = false + + /** + A list of the loaded fonts + */ + public static var loadedFonts: [String] = [] + + /** + Load all fonts found in a specific bundle. If no value is entered, it defaults to NSBundle.mainBundle(). + */ + public class func blast(bundle: NSBundle = NSBundle.mainBundle()) { + blast(bundle, completion: nil) + } + + /** + Load all fonts found in a specific bundle. If no value is entered, it defaults to NSBundle.mainBundle(). + + - returns: An array of strings constaining the names of the fonts that were loaded. + */ + public class func blast(bundle: NSBundle = NSBundle.mainBundle(), completion handler: ([String]->Void)?) { + let path = bundle.bundlePath + loadFontsForBundleWithPath(path) + loadFontsFromBundlesFoundInBundle(path) + handler?(loadedFonts) + } +} + + +// MARK: - Helpers (Font Loading) + +private extension FontBlaster { + /** + Loads all fonts found in a bundle. + + - parameter path: The absolute path to the bundle. + */ + class func loadFontsForBundleWithPath(path: String) { + do { + let contents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(path) + let fonts = fontsFromPath(path: path, contents: contents) + if !fonts.isEmpty { + for font in fonts { + loadFont(font) + } + } else { + printStatus(status: "No fonts were found in the bundle path: \(path).") + } + } catch let error as NSError { + printStatus(status: "There was an error loading fonts from the bundle. \nPath: \(path).\nError: \(error)") + } + } + + /** + Loads all fonts found in a bundle that is loaded within another bundle. + + - parameter path: The absolute path to the bundle. + */ + class func loadFontsFromBundlesFoundInBundle(path: String) { + + do { + + let contents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(path) + + for item in contents { + + if let url = NSURL(string: path) where item.containsString(".bundle"), + let urlPath = url.URLByAppendingPathComponent(item), + urlPathString = urlPath.absoluteString { + + loadFontsForBundleWithPath(urlPathString) + + } + + } + + } catch let error as NSError { + printStatus(status: "There was an error accessing bundle with path. \nPath: \(path).\nError: \(error)") + } + + } + + /** + Loads a specific font. + + - parameter font: The font to load. + */ + class func loadFont(font: Font) { + let fontPath: FontPath = font.path + let fontName: FontName = font.name + let fontExtension: FontExtension = font.ext + + guard let fontFileURL = NSBundle(path: fontPath)?.URLForResource(fontName, withExtension: fontExtension) else { + printStatus(status: "Could not unwrap the file URL for the resource with name: \(fontName) and extension \(fontExtension)") + return + } + + var fontError: Unmanaged? + + if let fontData = NSData(contentsOfURL: fontFileURL), + dataProvider = CGDataProviderCreateWithCFData(fontData) { + + let fontRef = CGFontCreateWithDataProvider(dataProvider) + + if CTFontManagerRegisterGraphicsFont(fontRef, &fontError) { + + if let postScriptName = CGFontCopyPostScriptName(fontRef) { + printStatus(status: "Successfully loaded font: '\(postScriptName)'.") + loadedFonts.append(String(postScriptName)) + } + + } else if let fontError = fontError?.takeRetainedValue() { + let errorDescription = CFErrorCopyDescription(fontError) + printStatus(status: "Failed to load font '\(fontName)': \(errorDescription)") + } + + } else { + + guard let fontError = fontError?.takeRetainedValue() else { + printStatus(status: "Failed to load font '\(fontName)'.") + return + } + + let errorDescription = CFErrorCopyDescription(fontError) + printStatus(status: "Failed to load font '\(fontName)': \(errorDescription)") + } + + } +} + + +// MARK: - Helpers (Miscellaneous) + +private extension FontBlaster { + /** + Parses a font into its name and extension components. + + - parameter path: The absolute path to the font file. + - parameter contents: The contents of an NSBundle as an array of String objects. + - returns: A tuple with the font's name and extension. + */ + class func fontsFromPath(path path: String, contents: [NSString]) -> [Font] { + var fonts = [Font]() + for fontName in contents { + var parsedFont: (FontName, FontExtension)? + + if fontName.containsString(SupportedFontExtensions.TrueTypeFont.rawValue) || fontName.containsString(SupportedFontExtensions.OpenTypeFont.rawValue) { + parsedFont = fontFromName(fontName as String) + } + + if let parsedFont = parsedFont { + let font: Font = (path, parsedFont.0, parsedFont.1) + fonts.append(font) + } + } + + return fonts + } + + /** + Parses a font into its name and extension components. + + - parameter The: name of the font. + - returns: A tuple with the font's name and extension. + */ + class func fontFromName(name: String) -> (FontName, FontExtension) { + let components = name.characters.split{$0 == "."}.map { String($0) } + return (components[0], components[1]) + } + + /** + Prints debug messages to the console if debugEnabled is set to true. + + - parameter The: status to print to the console. + */ + class func printStatus(status status: String) { + if debugEnabled == true { + print("[FontBlaster]: \(status)") + } + } +} diff --git a/Vendor/HAControls/HADiscreteSlider.swift b/Vendor/HAControls/HADiscreteSlider.swift index 42f069d28..709e7c26b 100644 --- a/Vendor/HAControls/HADiscreteSlider.swift +++ b/Vendor/HAControls/HADiscreteSlider.swift @@ -191,7 +191,7 @@ class HADiscreteSlider : UIControl { // Track switch self.trackStyle { case .Rectangular: - CGContextAddRect(ctx, self.trackRectangle) + CGContextAddRect(ctx!, self.trackRectangle) break case .Image: @@ -199,13 +199,13 @@ class HADiscreteSlider : UIControl { if let imageName = self.trackImage { let image = UIImage(named:imageName)! let centered = CGRectMake((self.frame.size.width/2)-(image.size.width/2), (self.frame.size.height/2)-(image.size.height/2), image.size.width, image.size.height) - CGContextDrawImage(ctx, centered, image.CGImage) + CGContextDrawImage(ctx!, centered, image.CGImage!) } break case .Invisible, .Rounded, .IOS: let path: UIBezierPath = UIBezierPath(roundedRect: self.trackRectangle, cornerRadius: self.trackRectangle.size.height/2) - CGContextAddPath(ctx, path.CGPath) + CGContextAddPath(ctx!, path.CGPath) break } @@ -217,10 +217,10 @@ class HADiscreteSlider : UIControl { switch self.tickStyle { case .Rounded: let path = UIBezierPath(roundedRect: rectangle, cornerRadius: rectangle.size.height/2) - CGContextAddPath(ctx, path.CGPath) + CGContextAddPath(ctx!, path.CGPath) break case .Rectangular: - CGContextAddRect(ctx, rectangle) + CGContextAddRect(ctx!, rectangle) break case .Image: // Draw image if exists @@ -228,7 +228,7 @@ class HADiscreteSlider : UIControl { if let imageName = self.tickImage { let image = UIImage(named: imageName)! let centered = CGRectMake(rectangle.origin.x+(rectangle.size.width/2)-(image.size.width/2), rectangle.origin.y+(rectangle.size.height/2)-(image.size.height/2), image.size.width, image.size.height) - CGContextDrawImage(ctx, centered, image.CGImage) + CGContextDrawImage(ctx!, centered, image.CGImage!) } break @@ -239,8 +239,8 @@ class HADiscreteSlider : UIControl { } // iOS UISlider aka .IOS does not have ticks - CGContextSetFillColorWithColor(ctx, self.tintColor.CGColor) - CGContextFillPath(ctx) + CGContextSetFillColorWithColor(ctx!, self.tintColor.CGColor) + CGContextFillPath(ctx!) // For colored track, we overlay a CALayer, which will animate along with the cursor if .IOS == self.trackStyle { var frame = self.trackRectangle @@ -388,8 +388,8 @@ class HADiscreteSlider : UIControl { self.touchUp(touches) } - override func touchesCancelled(touches: Set?, withEvent event: UIEvent?) { - self.touchUp(touches!) + override func touchesCancelled(touches: Set, withEvent event: UIEvent?) { + self.touchUp(touches) } func touchDown(touches: NSSet, duration: NSTimeInterval) {