Skip to content

Commit e189467

Browse files
committed
[Fix] font bug
1 parent 6b1fc6a commit e189467

File tree

3 files changed

+235
-127
lines changed

3 files changed

+235
-127
lines changed

Sources/ZMarkupParser/Core/MarkupStyle/MarkupStyleFont.swift

Lines changed: 138 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -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

223242
extension 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

Comments
 (0)