Determine if unicode character has a glyph in UIFont

匿名 (未验证) 提交于 2019-12-03 02:01:02

问题:

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))")


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!