@@ -51,25 +51,50 @@ public struct MarkupStyleFont: MarkupStyleItem {
5151 }
5252 #endif
5353 }
54- public enum FontWeightStyle : String {
54+ public enum FontWeightStyle : String , CaseIterable {
5555 case ultraLight, light, thin, regular, medium, semibold, bold, heavy, black
5656
57+ public init ? ( rawValue: String ) {
58+ guard let matchedStyle = FontWeightStyle . allCases. first ( where: { style in
59+ return rawValue. lowercased ( ) . contains ( style. rawValue)
60+ } ) else {
61+ return nil
62+ }
63+
64+ self = matchedStyle
65+ }
66+
5767 #if canImport(UIKit)
5868 init ? ( font: UIFont ) {
59- guard let weightName = font. fontDescriptor. object ( forKey: . face) as? String else {
60- return nil
69+ if let traits = font. fontDescriptor. fontAttributes [ . traits] as? [ UIFontDescriptor . TraitKey : Any ] , let weight = traits [ . weight] as? UIFont . Weight {
70+ self = weight. convertFontWeightStyle ( )
71+ return
72+ } else if font. fontDescriptor. symbolicTraits. contains ( . traitBold) {
73+ self = . bold
74+ return
75+ } else if let weightName = font. fontDescriptor. object ( forKey: . face) as? String , let weight = Self . init ( rawValue: weightName) {
76+ self = weight
77+ return
6178 }
62- self . init ( rawValue: weightName. lowercased ( ) )
79+
80+ return nil
6381 }
6482 #elseif canImport(AppKit)
6583 init ? ( font: NSFont ) {
66- guard let weightName = font. fontDescriptor. object ( forKey: . face) as? String else {
67- return nil
84+ if let traits = font. fontDescriptor. fontAttributes [ . traits] as? [ NSFontDescriptor . TraitKey : Any ] , let weight = traits [ . weight] as? NSFont . Weight {
85+ self = weight. convertFontWeightStyle ( )
86+ return
87+ } else if font. fontDescriptor. symbolicTraits. contains ( . bold) {
88+ self = . bold
89+ return
90+ } else if let weightName = font. fontDescriptor. object ( forKey: . face) as? String , let weight = Self . init ( rawValue: weightName) {
91+ self = weight
92+ return
6893 }
69- self . init ( rawValue: weightName. lowercased ( ) )
94+
95+ return nil
7096 }
7197 #endif
72-
7398 }
7499
75100 public var size : CGFloat ?
@@ -115,71 +140,38 @@ extension MarkupStyleFont {
115140 func getFont( ) -> UIFont ? {
116141 guard !isNil( ) else { return nil }
117142
143+ var traits : [ UIFontDescriptor . SymbolicTraits ] = [ ]
144+
118145 let size = ( self . size ?? MarkupStyle . default. font. size) ?? UIFont . systemFontSize
146+ let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
119147
120148 // There is no direct method in UIFont to specify the font family, italic and weight together.
149+
150+ let font : UIFont
151+ if let familyFont = self . familyName? . getFont ( size: size) {
152+ // Custom Font
153+ font = familyFont
154+ } else {
155+ // System Font
156+ font = UIFont . systemFont ( ofSize: size, weight: weight)
157+ }
121158
122- if let italic = self . italic, italic == true {
123- // italic
124-
125- let font : UIFont
126- if let familyFont = self . familyName? . getFont ( size: size) {
127- font = familyFont
128- } else {
129- font = UIFont . systemFont ( ofSize: size)
130- }
131-
132- if let weight = self . weight {
133- let needBold : Bool
134- switch weight {
135- case . style( let style) :
136- switch style {
137- case . ultraLight, . light, . thin, . regular:
138- needBold = false
139- case . medium, . semibold, . bold, . heavy, . black:
140- needBold = true
141- }
142- case . rawValue( let value) :
143- if value < UIFont . Weight. medium. rawValue {
144- needBold = false
145- } else {
146- needBold = true
147- }
148- }
149-
150- if needBold {
151- // italic+bold
152- return withTraits ( font: font, traits: . traitItalic, . traitBold)
153- } else {
154- // italic
155- return withTraits ( font: font, traits: . traitItalic)
156- }
157- } else {
158- // italic
159- return withTraits ( font: font, traits: . traitItalic)
160- }
159+ if weight. rawValue >= UIFont . Weight. medium. rawValue {
160+ traits. append ( . traitBold)
161+ }
162+
163+ if let italic = self . italic, italic {
164+ traits. append ( . traitItalic)
165+ }
166+
167+ if traits. isEmpty {
168+ return font
161169 } else {
162- if let familyFont = self . familyName? . getFont ( size: size) {
163- if let _ = self . weight {
164- // weight
165- return withTraits ( font: familyFont, traits: . traitBold)
166- } else {
167- // normal
168- return familyFont
169- }
170- } else {
171- if let weight = self . weight {
172- // weight
173- return UIFont . systemFont ( ofSize: size, weight: weight. convertToUIFontWeight ( ) )
174- } else {
175- // normal
176- return UIFont . systemFont ( ofSize: size)
177- }
178- }
170+ return withTraits ( font: font, traits: traits)
179171 }
180172 }
181173
182- private func withTraits( font: UIFont , traits: UIFontDescriptor . SymbolicTraits ... ) -> UIFont {
174+ private func withTraits( font: UIFont , traits: [ UIFontDescriptor . SymbolicTraits ] ) -> UIFont {
183175 guard let descriptor = font. fontDescriptor
184176 . withSymbolicTraits ( UIFontDescriptor . SymbolicTraits ( traits) ) else {
185177 return font
@@ -188,7 +180,7 @@ extension MarkupStyleFont {
188180 }
189181}
190182
191- public extension MarkupStyleFont . FontWeight {
183+ extension MarkupStyleFont . FontWeight {
192184 func convertToUIFontWeight( ) -> UIFont . Weight {
193185 switch self {
194186 case . style( let style) :
@@ -218,6 +210,33 @@ public extension MarkupStyleFont.FontWeight {
218210 }
219211}
220212
213+ private extension UIFont . Weight {
214+ func convertFontWeightStyle( ) -> MarkupStyleFont . FontWeightStyle {
215+ switch self {
216+ case . regular:
217+ return . regular
218+ case . ultraLight:
219+ return . ultraLight
220+ case . light:
221+ return . light
222+ case . thin:
223+ return . thin
224+ case . medium:
225+ return . medium
226+ case . semibold:
227+ return . semibold
228+ case . bold:
229+ return . bold
230+ case . heavy:
231+ return . heavy
232+ case . black:
233+ return . black
234+ default :
235+ return . regular
236+ }
237+ }
238+ }
239+
221240#elseif canImport(AppKit)
222241
223242extension MarkupStyleFont {
@@ -235,77 +254,44 @@ extension MarkupStyleFont {
235254 func getFont( ) -> NSFont ? {
236255 guard !isNil( ) else { return nil }
237256
257+ var traits : [ NSFontDescriptor . SymbolicTraits ] = [ ]
258+
238259 let size = ( self . size ?? MarkupStyle . default. font. size) ?? NSFont . systemFontSize
260+ let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
239261
240262 // There is no direct method in UIFont to specify the font family, italic and weight together.
263+
264+ let font : NSFont
265+ if let familyFont = self . familyName? . getFont ( size: size) {
266+ // Custom Font
267+ font = familyFont
268+ } else {
269+ // System Font
270+ font = NSFont . systemFont ( ofSize: size, weight: weight)
271+ }
241272
242- if let italic = self . italic, italic == true {
243- // italic
244-
245- let font : NSFont
246- if let familyFont = self . familyName? . getFont ( size: size) {
247- font = familyFont
248- } else {
249- font = NSFont . systemFont ( ofSize: size)
250- }
251-
252- if let weight = self . weight {
253- let needBold : Bool
254- switch weight {
255- case . style( let style) :
256- switch style {
257- case . ultraLight, . light, . thin, . regular:
258- needBold = false
259- case . medium, . semibold, . bold, . heavy, . black:
260- needBold = true
261- }
262- case . rawValue( let value) :
263- if value < NSFont . Weight. medium. rawValue {
264- needBold = false
265- } else {
266- needBold = true
267- }
268- }
269-
270- if needBold {
271- // italic+bold
272- return withTraits ( font: font, traits: . italic, . bold)
273- } else {
274- // italic
275- return withTraits ( font: font, traits: . italic)
276- }
277- } else {
278- // italic
279- return withTraits ( font: font, traits: . italic)
280- }
273+ if weight. rawValue >= NSFont . Weight. medium. rawValue {
274+ traits. append ( . bold)
275+ }
276+
277+ if let italic = self . italic, italic {
278+ traits. append ( . italic)
279+ }
280+
281+ if traits. isEmpty {
282+ return font
281283 } else {
282- if let familyFont = self . familyName? . getFont ( size: size) {
283- if let _ = self . weight {
284- // weight
285- return withTraits ( font: familyFont, traits: . bold)
286- } else {
287- // normal
288- return familyFont
289- }
290- } else {
291- if let weight = self . weight {
292- // weight
293- return NSFont . systemFont ( ofSize: size, weight: weight. convertToUIFontWeight ( ) )
294- } else {
295- // normal
296- return NSFont . systemFont ( ofSize: size)
297- }
298- }
284+ return withTraits ( font: font, traits: traits)
299285 }
300286 }
301287
302- private func withTraits( font: NSFont , traits: NSFontDescriptor . SymbolicTraits ... ) -> NSFont {
303- let descriptor = font. fontDescriptor. withSymbolicTraits ( NSFontDescriptor . SymbolicTraits ( traits) )
288+ private func withTraits( font: NSFont , traits: [ NSFontDescriptor . SymbolicTraits ] ) -> NSFont {
289+ let descriptor = font. fontDescriptor. withSymbolicTraits ( NSFontDescriptor . SymbolicTraits ( traits) )
304290 return NSFont ( descriptor: descriptor, size: font. pointSize) ?? font
305291 }
306292}
307293
308- public extension MarkupStyleFont . FontWeight {
294+ private extension MarkupStyleFont . FontWeight {
309295 func convertToUIFontWeight( ) -> NSFont . Weight {
310296 switch self {
311297 case . style( let style) :
@@ -335,4 +321,31 @@ public extension MarkupStyleFont.FontWeight {
335321 }
336322}
337323
324+ private extension NSFont . Weight {
325+ func convertFontWeightStyle( ) -> MarkupStyleFont . FontWeightStyle {
326+ switch self {
327+ case . regular:
328+ return . regular
329+ case . ultraLight:
330+ return . ultraLight
331+ case . light:
332+ return . light
333+ case . thin:
334+ return . thin
335+ case . medium:
336+ return . medium
337+ case . semibold:
338+ return . semibold
339+ case . bold:
340+ return . bold
341+ case . heavy:
342+ return . heavy
343+ case . black:
344+ return . black
345+ default :
346+ return . regular
347+ }
348+ }
349+ }
350+
338351#endif
0 commit comments