I want to find out if a certain unicode character has a glyph representation even if by a cascading font. For example, let's say I am using UIFont.systemFont(withSize:18) and a string \u{1CDA} and would like to find out if this font will display the graphical representation of this character, and not a default question mark representation (ie there's no graphical representation, even by the supporting cascade fonts).
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
This works for me. Swift 3, XCode 8.6 version:
import UIKit import CoreText extension Font { public func hasGlyph(utf32 character:UInt32) -> Bool { var code_point: [UniChar] = [ UniChar.init(truncatingBitPattern: character), UniChar.init(truncatingBitPattern: character >> 16) ] var glyphs: [CGGlyph] = [0,0] let result = CTFontGetGlyphsForCharacters(self as CTFont, &code_point, &glyphs, glyphs.count) return result } } public class Glypher { let font:UIFont var support:[CTFont] = [] public init(for font:UIFont, languages:[String] = ["en"]) { self.font = font let languages = languages as CFArray let result = CTFontCopyDefaultCascadeListForLanguages(font as CTFont, languages) let array = result as! Array for descriptor in array { support.append(CTFontCreateWithFontDescriptor(descriptor,18,nil)) } } public func isGlyph(_ point:UInt32) -> Bool { return font.hasGlyph(utf32:point) || isGlyphSupported(point) } public func isGlyphSupported(_ point:UInt32) -> Bool { for font in support { var code_point: [UniChar] = [ UniChar.init(truncatingBitPattern: point), UniChar.init(truncatingBitPattern: point >> 16) ] var glyphs: [CGGlyph] = [0, 0] let result = CTFontGetGlyphsForCharacters(font as CTFont, &code_point, &glyphs, glyphs.count) if result { return true } } return false } } let glypher = Glypher(for:UIFont.systemFont(ofSize:18)) if glypher.isGlyph(0x1CDA) { print("bingo!") } 回答2:
This may work too, it doesn't check the glyph, but it checks the character set
import CoreText func isSupported(unicode: UnicodeScalar, font: UIFont) -> Bool { let coreFont: CTFont = font let characterSet: CharacterSet = CTFontCopyCharacterSet(coreFont) as CharacterSet return characterSet.contains(unicode) } Example test:
let testString = "R" let font = UIFont.boldSystemFont(ofSize: 10.0) print("\(isSupported(unicode: testString.unicodeScalars.first!, font: font))")