WikipediaBrown
WikipediaBrown

Reputation: 817

CTFontGetGlyphsForCharacters Returns false when passing emoji

In a class conforming to NSLayoutManagerDelegate I implement this method:

func layoutManager(_ layoutManager: NSLayoutManager,
                       shouldGenerateGlyphs glyphs: UnsafePointer<CGGlyph>,
                       properties props: UnsafePointer<NSLayoutManager.GlyphProperty>,
                       characterIndexes charIndexes: UnsafePointer<Int>,
                       font aFont: UIFont,
                       forGlyphRange glyphRange: NSRange) -> Int {

        // First, make sure we'll be able to access the NSTextStorage.
        guard let textStorage = layoutManager.textStorage
        else { return 0 }

        // Get the first and last characters indexes for this glyph range,
        // and from that create the characters indexes range.
        let firstCharIndex = charIndexes[0]
        let lastCharIndex = charIndexes[glyphRange.length - 1]
        let charactersRange = NSRange(location: firstCharIndex, length: lastCharIndex - firstCharIndex + 1)
        
        var bulletPointRanges = [NSRange]()
        var hiddenRanges = [NSRange]()
        let finalGlyphs = UnsafeMutablePointer<CGGlyph>(mutating: glyphs)
        
        // Generate the Middle Dot glyph using aFont.
        
        let middleDot: [UniChar] = [0x00B7] // Middle Dot: U+0x00B7
        var myGlyphs: [CGGlyph] = [0]
        
        // Get glyphs for `middleDot` character
        guard CTFontGetGlyphsForCharacters(aFont, middleDot, &myGlyphs, middleDot.count) == true
        else { fatalError("Failed to get the glyphs for characters \(middleDot).") }
}

The problem is that CTFontGetGlyphsForCharacters returns false when I type an emoji into the textview. I think it might have something to do with UTF-8 vs. UTF-16 but I'm kind of out of my depth a little here. Little help?

Upvotes: 0

Views: 198

Answers (1)

Scott Thompson
Scott Thompson

Reputation: 23701

The font you are using does not have a glyph for that particular character.

The system maintains a list of "font fallbacks" for times when the specific font you are trying to look at does not have a glyph but another font might.

The list of fallbacks is given by CTFontCopyDefaultCascadeListForLanguages, but since you're at the point where you are being asked for the glyph from a particular font, it seems that fallback generation should be handled higher up in the chain.

You should probably return 0 to indicate that the layout manager should use it's default behavior.

Upvotes: 1

Related Questions