@@ -51,25 +51,50 @@ public struct MarkupStyleFont: MarkupStyleItem {
51
51
}
52
52
#endif
53
53
}
54
- public enum FontWeightStyle : String {
54
+ public enum FontWeightStyle : String , CaseIterable {
55
55
case ultraLight, light, thin, regular, medium, semibold, bold, heavy, black
56
56
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
+
57
67
#if canImport(UIKit)
58
68
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
61
78
}
62
- self . init ( rawValue: weightName. lowercased ( ) )
79
+
80
+ return nil
63
81
}
64
82
#elseif canImport(AppKit)
65
83
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
68
93
}
69
- self . init ( rawValue: weightName. lowercased ( ) )
94
+
95
+ return nil
70
96
}
71
97
#endif
72
-
73
98
}
74
99
75
100
public var size : CGFloat ?
@@ -115,71 +140,38 @@ extension MarkupStyleFont {
115
140
func getFont( ) -> UIFont ? {
116
141
guard !isNil( ) else { return nil }
117
142
143
+ var traits : [ UIFontDescriptor . SymbolicTraits ] = [ ]
144
+
118
145
let size = ( self . size ?? MarkupStyle . default. font. size) ?? UIFont . systemFontSize
146
+ let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
119
147
120
148
// 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
+ }
121
158
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
161
169
} 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)
179
171
}
180
172
}
181
173
182
- private func withTraits( font: UIFont , traits: UIFontDescriptor . SymbolicTraits ... ) -> UIFont {
174
+ private func withTraits( font: UIFont , traits: [ UIFontDescriptor . SymbolicTraits ] ) -> UIFont {
183
175
guard let descriptor = font. fontDescriptor
184
176
. withSymbolicTraits ( UIFontDescriptor . SymbolicTraits ( traits) ) else {
185
177
return font
@@ -188,7 +180,7 @@ extension MarkupStyleFont {
188
180
}
189
181
}
190
182
191
- public extension MarkupStyleFont . FontWeight {
183
+ extension MarkupStyleFont . FontWeight {
192
184
func convertToUIFontWeight( ) -> UIFont . Weight {
193
185
switch self {
194
186
case . style( let style) :
@@ -218,6 +210,33 @@ public extension MarkupStyleFont.FontWeight {
218
210
}
219
211
}
220
212
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
+
221
240
#elseif canImport(AppKit)
222
241
223
242
extension MarkupStyleFont {
@@ -235,77 +254,44 @@ extension MarkupStyleFont {
235
254
func getFont( ) -> NSFont ? {
236
255
guard !isNil( ) else { return nil }
237
256
257
+ var traits : [ NSFontDescriptor . SymbolicTraits ] = [ ]
258
+
238
259
let size = ( self . size ?? MarkupStyle . default. font. size) ?? NSFont . systemFontSize
260
+ let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
239
261
240
262
// 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
+ }
241
272
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
281
283
} 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)
299
285
}
300
286
}
301
287
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) )
304
290
return NSFont ( descriptor: descriptor, size: font. pointSize) ?? font
305
291
}
306
292
}
307
293
308
- public extension MarkupStyleFont . FontWeight {
294
+ private extension MarkupStyleFont . FontWeight {
309
295
func convertToUIFontWeight( ) -> NSFont . Weight {
310
296
switch self {
311
297
case . style( let style) :
@@ -335,4 +321,31 @@ public extension MarkupStyleFont.FontWeight {
335
321
}
336
322
}
337
323
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
+
338
351
#endif
0 commit comments