@@ -24,7 +24,7 @@ public struct MarkupStyleFont: MarkupStyleItem {
24
24
}
25
25
public enum FontFamily {
26
26
case familyNames( [ String ] )
27
-
27
+
28
28
#if canImport(UIKit)
29
29
func getFont( size: CGFloat ) -> UIFont ? {
30
30
switch self {
@@ -53,106 +53,105 @@ public struct MarkupStyleFont: MarkupStyleItem {
53
53
}
54
54
public enum FontWeightStyle : String , CaseIterable {
55
55
case ultraLight, light, thin, regular, medium, semibold, bold, heavy, black
56
-
56
+
57
57
public init ? ( rawValue: String ) {
58
58
guard let matchedStyle = FontWeightStyle . allCases. first ( where: { style in
59
59
return rawValue. lowercased ( ) . contains ( style. rawValue)
60
60
} ) else {
61
61
return nil
62
62
}
63
-
63
+
64
64
self = matchedStyle
65
65
}
66
-
66
+
67
67
#if canImport(UIKit)
68
68
init ? ( font: UIFont ) {
69
69
if let traits = font. fontDescriptor. fontAttributes [ . traits] as? [ UIFontDescriptor . TraitKey : Any ] , let weight = traits [ . weight] as? UIFont . Weight {
70
70
self = weight. convertFontWeightStyle ( )
71
71
return
72
- } else if font. fontDescriptor. symbolicTraits. contains ( . traitBold) {
73
- self = . bold
74
- return
75
72
} else if let weightName = font. fontDescriptor. object ( forKey: . face) as? String , let weight = Self . init ( rawValue: weightName) {
76
73
self = weight
77
74
return
78
75
}
79
-
76
+
80
77
return nil
81
78
}
82
79
#elseif canImport(AppKit)
83
80
init ? ( font: NSFont ) {
84
81
if let traits = font. fontDescriptor. fontAttributes [ . traits] as? [ NSFontDescriptor . TraitKey : Any ] , let weight = traits [ . weight] as? NSFont . Weight {
85
82
self = weight. convertFontWeightStyle ( )
86
83
return
87
- } else if font. fontDescriptor. symbolicTraits. contains ( . bold) {
88
- self = . bold
89
- return
90
84
} else if let weightName = font. fontDescriptor. object ( forKey: . face) as? String , let weight = Self . init ( rawValue: weightName) {
91
85
self = weight
92
86
return
93
87
}
94
-
88
+
95
89
return nil
96
90
}
97
91
#endif
98
92
}
99
-
93
+
100
94
public var size : CGFloat ?
101
95
public var weight : FontWeight ?
102
96
public var italic : Bool ?
97
+ public var bold : Bool ?
103
98
public var familyName : FontFamily ?
104
-
105
- public init ( size: CGFloat ? = nil , weight: FontWeight ? = nil , italic: Bool ? = nil , familyName: FontFamily ? = nil ) {
99
+
100
+ public init ( size: CGFloat ? = nil , weight: FontWeight ? = nil , bold : Bool ? = nil , italic: Bool ? = nil , familyName: FontFamily ? = nil ) {
106
101
self . size = size
107
102
self . weight = weight
103
+ self . bold = bold
108
104
self . italic = italic
109
105
self . familyName = familyName
110
106
}
111
-
107
+
112
108
mutating func fillIfNil( from: MarkupStyleFont ? ) {
113
109
self . size = self . size ?? from? . size
114
110
self . weight = self . weight ?? from? . weight
115
111
self . italic = self . italic ?? from? . italic
112
+ self . bold = self . bold ?? from? . bold
116
113
self . familyName = self . familyName ?? from? . familyName
117
114
}
118
-
115
+
119
116
func isNil( ) -> Bool {
120
117
return !( [ size,
121
- weight,
122
- italic,
123
- familyName] as [ Any ? ] ) . contains ( where: { $0 != nil } )
118
+ weight,
119
+ italic,
120
+ bold,
121
+ familyName] as [ Any ? ] ) . contains ( where: { $0 != nil } )
124
122
}
125
-
123
+
126
124
func sizeOf( string: String ) -> CGSize ? {
127
125
guard let font = getFont ( ) else {
128
126
return nil
129
127
}
130
-
128
+
131
129
return ( string as NSString ) . size ( withAttributes: [ . font: font] )
132
130
}
133
131
}
134
132
135
133
#if canImport(UIKit)
136
134
137
135
extension MarkupStyleFont {
138
-
136
+
139
137
public init ( _ font: UIFont ) {
140
138
self . size = font. pointSize
141
139
self . italic = font. fontDescriptor. symbolicTraits. contains ( . traitItalic)
140
+ self . bold = font. fontDescriptor. symbolicTraits. contains ( . traitBold)
142
141
if let fontWeight = FontWeightStyle . init ( font: font) {
143
142
self . weight = FontWeight . style ( fontWeight)
144
143
}
145
144
self . familyName = . familyNames( [ font. familyName] )
146
145
}
147
-
146
+
148
147
func getFont( ) -> UIFont ? {
149
148
guard !isNil( ) else { return nil }
150
-
151
- var traits : [ UIFontDescriptor . SymbolicTraits ] = [ ]
152
-
149
+
150
+ var traits : UIFontDescriptor . SymbolicTraits = [ ]
151
+
153
152
let size = ( self . size ?? MarkupStyle . default. font. size) ?? UIFont . systemFontSize
154
153
let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
155
-
154
+
156
155
// There is no direct method in UIFont to specify the font family, italic and weight together.
157
156
158
157
let font : UIFont
@@ -163,28 +162,16 @@ extension MarkupStyleFont {
163
162
// System Font
164
163
font = UIFont . systemFont ( ofSize: size, weight: weight)
165
164
}
166
-
167
- if weight . rawValue >= UIFont . Weight . medium . rawValue {
168
- traits. append ( . traitBold)
165
+
166
+ if bold == true {
167
+ traits. insert ( . traitBold)
169
168
}
170
-
169
+
171
170
if let italic = self . italic, italic {
172
- traits. append ( . traitItalic)
173
- }
174
-
175
- if traits. isEmpty {
176
- return font
177
- } else {
178
- return withTraits ( font: font, traits: traits)
171
+ traits. insert ( . traitItalic)
179
172
}
180
- }
181
-
182
- private func withTraits( font: UIFont , traits: [ UIFontDescriptor . SymbolicTraits ] ) -> UIFont {
183
- guard let descriptor = font. fontDescriptor
184
- . withSymbolicTraits ( UIFontDescriptor . SymbolicTraits ( traits) ) else {
185
- return font
186
- }
187
- return UIFont ( descriptor: descriptor, size: font. pointSize)
173
+
174
+ return font. with ( weight: weight, symbolicTraits: traits)
188
175
}
189
176
}
190
177
@@ -245,6 +232,27 @@ private extension UIFont.Weight {
245
232
}
246
233
}
247
234
235
+ private extension UIFont {
236
+
237
+ /// Returns a font object that is the same as the receiver but which has the specified weight and symbolic traits
238
+ func with( weight: Weight , symbolicTraits: UIFontDescriptor . SymbolicTraits ) -> UIFont {
239
+
240
+ var mergedsymbolicTraits = fontDescriptor. symbolicTraits
241
+ mergedsymbolicTraits. formUnion ( symbolicTraits)
242
+
243
+ var traits = fontDescriptor. fontAttributes [ . traits] as? [ UIFontDescriptor . TraitKey : Any ] ?? [ : ]
244
+ traits [ . weight] = weight
245
+ traits [ . symbolic] = mergedsymbolicTraits. rawValue
246
+
247
+ var fontAttributes : [ UIFontDescriptor . AttributeName : Any ] = [ : ]
248
+ fontAttributes [ . family] = familyName
249
+ fontAttributes [ . traits] = traits
250
+
251
+ let font = UIFont ( descriptor: UIFontDescriptor ( fontAttributes: fontAttributes) , size: pointSize)
252
+ return UIFontMetrics . default. scaledFont ( for: font)
253
+ }
254
+ }
255
+
248
256
#elseif canImport(AppKit)
249
257
250
258
extension MarkupStyleFont {
@@ -258,15 +266,15 @@ extension MarkupStyleFont {
258
266
self . familyName = . familyNames( [ familyName] )
259
267
}
260
268
}
261
-
269
+
262
270
func getFont( ) -> NSFont ? {
263
271
guard !isNil( ) else { return nil }
264
-
265
- var traits : [ NSFontDescriptor . SymbolicTraits ] = [ ]
266
-
272
+
273
+ var traits : NSFontDescriptor . SymbolicTraits = [ ]
274
+
267
275
let size = ( self . size ?? MarkupStyle . default. font. size) ?? NSFont . systemFontSize
268
276
let weight = self . weight? . convertToUIFontWeight ( ) ?? . regular
269
-
277
+
270
278
// There is no direct method in UIFont to specify the font family, italic and weight together.
271
279
272
280
let font : NSFont
@@ -277,25 +285,16 @@ extension MarkupStyleFont {
277
285
// System Font
278
286
font = NSFont . systemFont ( ofSize: size, weight: weight)
279
287
}
280
-
281
- if weight . rawValue >= NSFont . Weight . medium . rawValue {
282
- traits. append ( . bold)
288
+
289
+ if bold == true {
290
+ traits. insert ( . bold)
283
291
}
284
-
292
+
285
293
if let italic = self . italic, italic {
286
- traits. append ( . italic)
287
- }
288
-
289
- if traits. isEmpty {
290
- return font
291
- } else {
292
- return withTraits ( font: font, traits: traits)
294
+ traits. insert ( . italic)
293
295
}
294
- }
295
-
296
- private func withTraits( font: NSFont , traits: [ NSFontDescriptor . SymbolicTraits ] ) -> NSFont {
297
- let descriptor = font. fontDescriptor. withSymbolicTraits ( NSFontDescriptor . SymbolicTraits ( traits) )
298
- return NSFont ( descriptor: descriptor, size: font. pointSize) ?? font
296
+
297
+ return font. with ( weight: weight, symbolicTraits: traits)
299
298
}
300
299
}
301
300
@@ -356,4 +355,26 @@ private extension NSFont.Weight {
356
355
}
357
356
}
358
357
358
+ private extension NSFont {
359
+
360
+ /// Returns a font object that is the same as the receiver but which has the specified weight and symbolic traits
361
+ func with( weight: Weight , symbolicTraits: NSFontDescriptor . SymbolicTraits ) -> NSFont {
362
+
363
+ var mergedsymbolicTraits = fontDescriptor. symbolicTraits
364
+ mergedsymbolicTraits. formUnion ( symbolicTraits)
365
+
366
+ var traits = fontDescriptor. fontAttributes [ . traits] as? [ NSFontDescriptor . TraitKey : Any ] ?? [ : ]
367
+ traits [ . weight] = weight
368
+ traits [ . symbolic] = mergedsymbolicTraits. rawValue
369
+
370
+ var fontAttributes : [ NSFontDescriptor . AttributeName : Any ] = [ : ]
371
+ fontAttributes [ . family] = familyName
372
+ fontAttributes [ . traits] = traits
373
+
374
+ let font = NSFont ( descriptor: NSFontDescriptor ( fontAttributes: fontAttributes) , size: pointSize)
375
+ // return UIFontMetrics.default.scaledFont(for: font)
376
+ return font ?? self
377
+ }
378
+ }
379
+
359
380
#endif
0 commit comments