Detect when a unicode character cannot be displayed correctly

后端 未结 2 864
傲寒
傲寒 2020-12-06 07:42

Some unicode characters cannot be displayed on iOS but are displayed correctly on macOS. Similarly, some unicode characters that iOS can display cannot be displayed on watch

相关标签:
2条回答
  • 2020-12-06 07:53

    Compare against the known, undefined character U+1FFF:

    /// - Parameter font: a UIFont
    /// - Returns: true if glyph exists
    func glyphAvailable(forFont font:UIFont) -> Bool {
        if let refUnicodePng = Character("\u{1fff}").png(forFont: font),
            let myPng = self.png(forFont: font) {
            return refUnicodePng != myPng
        }
        return false
    }
    

    using a png bitmap:

    /// - Parameter font: a UIFont
    /// - Returns: an optional png representation
    func png(forFont font: UIFont) -> Data? {
        let attributes = [NSAttributedStringKey.font: font]
        let charStr = "\(self)" as NSString
        let size = charStr.size(withAttributes: attributes)
    
        UIGraphicsBeginImageContext(size)
        charStr.draw(at: CGPoint(x: 0,y :0), withAttributes: attributes)
    
        var png:Data? = nil
        if let charImage = UIGraphicsGetImageFromCurrentImageContext() {
            png = UIImagePNGRepresentation(charImage)
        }
    
        UIGraphicsEndImageContext()
        return png
    }
    

    Answered here.

    0 讨论(0)
  • 2020-12-06 08:04

    You can use CTFontGetGlyphsForCharacters() to determine if a font has a glyph for a particular code point (note that supplementary characters need to be checked as surrogate pairs):

    CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica"), 12, NULL);
    const UniChar code_point[] = { 0xD83C, 0xDCA1 };  // U+1F0A1
    CGGlyph glyph[] = { 0, 0 };
    bool has_glyph = CTFontGetGlyphsForCharacters(font, code_point, glyph, 2);
    

    Or, in Swift:

    let font = CTFontCreateWithName("Helvetica", 12, nil)
    var code_point: [UniChar] = [0xD83C, 0xDCA1]
    var glyphs: [CGGlyph] = [0, 0]
    let has_glyph = CTFontGetGlyphsForCharacters(font, &code_point, &glyph, 2)
    

    If you want to check the complete set of fallback fonts that the system will try to load a glyph from, you will need to check all of the fonts returned by CTFontCopyDefaultCascadeListForLanguages(). Check the answer to this question for information on how the fallback font list is created.

    0 讨论(0)
提交回复
热议问题