I have setup a NSLayoutManagerDelegate to display emojis for ASCII text on iOS, iPadOS, and Mac Catalyst.
For the first character (e.g., ":"), I set the emoji glyph (e.g., "😀"). For the remainder (e.g., ")"), I use a .null property so it doesn't display.
This almost works, but it's using the default font instead of "Apple Color Emoji", so it appears as a text symbol.
Here is the delegate code. Note that I have verified that the font used for the emoji glyph is the emoji font.
Is there something else I should do to set the font?
For the first character (e.g., ":"), I set the emoji glyph (e.g., "😀"). For the remainder (e.g., ")"), I use a .null property so it doesn't display.
This almost works, but it's using the default font instead of "Apple Color Emoji", so it appears as a text symbol.
Here is the delegate code. Note that I have verified that the font used for the emoji glyph is the emoji font.
Code Block func layoutManager(_ layoutManager: NSLayoutManager, shouldGenerateGlyphs glyphs: UnsafePointer<CGGlyph>, properties: UnsafePointer<NSLayoutManager.GlyphProperty>, characterIndexes indexes: UnsafePointer<Int>, font: UIFont, forGlyphRange range: NSRange) -> Int { let count = range.length var glyphs = Array(UnsafeBufferPointer(start: glyphs, count: count)) var properties = Array(UnsafeBufferPointer(start: properties, count: count)) var indexes = Array(UnsafeBufferPointer(start: indexes, count: count)) var fonts = Array(repeating: font, count: count) if let textStorage = layoutManager.textStorage { for i in 0..<count { let range = NSRange(location: range.location + i, length: 1) textStorage.enumerateAttribute(Composition.Key.emojiText, in: range, options: .longestEffectiveRangeNotRequired) {(value, range, stop) in if let fragment = value as? Composition.Fragment { if range.location == fragment.range?.location { let string = NSAttributedString(string: fragment.text2, attributes: textStorage.attributes(at: range.location, effectiveRange: nil)) let line = CTLineCreateWithAttributedString(string) let runs = CTLineGetGlyphRuns(line) as! [CTRun] if let run = runs.first { if let attributes = CTRunGetAttributes(run) as NSDictionary? { let font = attributes[kCTFontAttributeName as String] as! UIFont if CTRunGetGlyphCount(run) == 1 { var glyph = CGGlyph() CTRunGetGlyphs(run, CFRange(location: 0, length: 1), &glyph) glyphs[i] = glyph properties[i] = [] fonts[i] = font } } } } else { glyphs[i] = CGGlyph() properties[i] = .null } } } } } for i in 0..<count { let range = NSRange(location: range.location + i, length: 1) layoutManager.setGlyphs(&glyphs[i], properties: &properties[i], characterIndexes: &indexes[i], font: fonts[i], forGlyphRange: range) } return count }
Is there something else I should do to set the font?