From 5702cea84342da69e4a552639308018d9e131999 Mon Sep 17 00:00:00 2001 From: Mihael Cholakov Date: Sat, 25 Aug 2018 21:49:30 +0300 Subject: [PATCH] Implements iOS support for AttributedStringOutputFormat --- .../Output/AttributedStringOutputFormat.swift | 87 +++++++++++++++---- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/Sources/Splash/Output/AttributedStringOutputFormat.swift b/Sources/Splash/Output/AttributedStringOutputFormat.swift index e28ac8a..7cc788e 100644 --- a/Sources/Splash/Output/AttributedStringOutputFormat.swift +++ b/Sources/Splash/Output/AttributedStringOutputFormat.swift @@ -5,19 +5,23 @@ */ #if os(macOS) - import Cocoa +#endif + +#if os(iOS) +import UIKit +#endif /// Output format to use to generate an NSAttributedString from the /// highlighted code. A `Theme` is used to determine what fonts and /// colors to use for the various tokens. public struct AttributedStringOutputFormat: OutputFormat { public var theme: Theme - + public init(theme: Theme) { self.theme = theme } - + public func makeBuilder() -> Builder { return Builder(theme: theme) } @@ -28,32 +32,33 @@ public extension AttributedStringOutputFormat { private let theme: Theme private lazy var font = loadFont() private var string = NSMutableAttributedString() - + fileprivate init(theme: Theme) { self.theme = theme } - + public mutating func addToken(_ token: String, ofType type: TokenType) { let color = theme.tokenColors[type] ?? Color(red: 1, green: 1, blue: 1) string.append(token, font: font, color: color) } - + public mutating func addPlainText(_ text: String) { string.append(text, font: font, color: theme.plainTextColor) } - + public mutating func addWhitespace(_ whitespace: String) { let color = Color(red: 1, green: 1, blue: 1) string.append(whitespace, font: font, color: color) } - + public func build() -> NSAttributedString { return NSAttributedString(attributedString: string) } - + + #if os(macOS) private mutating func loadFont() -> NSFont { let size = CGFloat(theme.font.size) - + switch theme.font.resource { case .system: return .defaultFont(ofSize: size) @@ -61,13 +66,26 @@ public extension AttributedStringOutputFormat { guard let font = NSFont.loaded(from: path, size: size) else { return .defaultFont(ofSize: size) } - + return font } } + #endif + + #if os(iOS) + private mutating func loadFont() -> UIFont { + + let size = CGFloat(theme.font.size) + let font = UIFont.defaultFont(ofSize: size) + return font + + } + #endif + } } +#if os(macOS) private extension NSMutableAttributedString { func append(_ string: String, font: NSFont, color: Color) { let color = NSColor( @@ -76,12 +94,12 @@ private extension NSMutableAttributedString { blue: CGFloat(color.blue), alpha: CGFloat(color.alpha) ) - + let attributedString = NSAttributedString(string: string, attributes: [ .foregroundColor: color, .font: font - ]) - + ]) + append(attributedString) } } @@ -94,21 +112,52 @@ private extension NSFont { .cfurlposixPathStyle, false ) - + guard let font = url.flatMap(CGDataProvider.init).flatMap(CGFont.init) else { return nil } - + return CTFontCreateWithGraphicsFont(font, size, nil, nil) } - + static func defaultFont(ofSize size: CGFloat) -> NSFont { guard let courier = loaded(from: "/Library/Fonts/Courier New.ttf", size: size) else { return .systemFont(ofSize: size) } - + return courier } } - +#endif + +#if os(iOS) +private extension NSMutableAttributedString { + func append(_ string: String, font: UIFont, color: Color) { + let color = UIColor( + red: CGFloat(color.red), + green: CGFloat(color.green), + blue: CGFloat(color.blue), + alpha: CGFloat(color.alpha) + ) + + let attributedString = NSAttributedString(string: string, attributes: [ + .foregroundColor: color, + .font: font + ]) + + append(attributedString) + } +} + +private extension UIFont { + + static func defaultFont(ofSize size: CGFloat) -> UIFont { + guard let menlo = UIFont(name: "Menlo-Regular", size: size) else { + return .systemFont(ofSize: size) + } + + return menlo + } + +} #endif