Post

Replies

Boosts

Views

Activity

Setting font with layoutManager.setGlyphs
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. &#9;func layoutManager(_ layoutManager: NSLayoutManager, shouldGenerateGlyphs glyphs: UnsafePointer&lt;CGGlyph&gt;, properties: UnsafePointer&lt;NSLayoutManager.GlyphProperty&gt;, characterIndexes indexes: UnsafePointer&lt;Int&gt;, font: UIFont, forGlyphRange range: NSRange) -> Int { &#9;&#9;let count = range.length &#9;&#9;var glyphs = Array(UnsafeBufferPointer(start: glyphs, count: count)) &#9;&#9;var properties = Array(UnsafeBufferPointer(start: properties, count: count)) &#9;&#9;var indexes = Array(UnsafeBufferPointer(start: indexes, count: count)) &#9;&#9;var fonts = Array(repeating: font, count: count) &#9;&#9;if let textStorage = layoutManager.textStorage { &#9;&#9;&#9;for i in 0..<count { &#9;&#9;&#9;&#9;let range = NSRange(location: range.location + i, length: 1) &#9;&#9;&#9;&#9;textStorage.enumerateAttribute(Composition.Key.emojiText, in: range, options: .longestEffectiveRangeNotRequired) {(value, range, stop) in &#9;&#9;&#9;&#9;&#9;if let fragment = value as? Composition.Fragment { &#9;&#9;&#9;&#9;&#9;&#9;if range.location == fragment.range?.location { &#9;&#9;&#9;&#9;&#9;&#9;&#9;let string = NSAttributedString(string: fragment.text2, attributes: textStorage.attributes(at: range.location, effectiveRange: nil)) &#9;&#9;&#9;&#9;&#9;&#9;&#9;let line = CTLineCreateWithAttributedString(string) &#9;&#9;&#9;&#9;&#9;&#9;&#9;let runs = CTLineGetGlyphRuns(line) as! [CTRun] &#9;&#9;&#9;&#9;&#9;&#9;&#9;if let run = runs.first { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if let attributes = CTRunGetAttributes(run) as NSDictionary? { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;let font = attributes[kCTFontAttributeName as String] as! UIFont &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if CTRunGetGlyphCount(run) == 1 { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;var glyph = CGGlyph() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;CTRunGetGlyphs(run, CFRange(location: 0, length: 1), &amp;glyph) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;glyphs[i] = glyph &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;properties[i] = [] &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;fonts[i] = font &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;} else { &#9;&#9;&#9;&#9;&#9;&#9;&#9;glyphs[i] = CGGlyph() &#9;&#9;&#9;&#9;&#9;&#9;&#9;properties[i] = .null &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;&#9;} &#9;&#9;} &#9;&#9;for i in 0..<count { &#9;&#9;&#9;let range = NSRange(location: range.location + i, length: 1) &#9;&#9;&#9;layoutManager.setGlyphs(&amp;glyphs[i], properties: &amp;properties[i], characterIndexes: &amp;indexes[i], font: fonts[i], forGlyphRange: range) &#9;&#9;} &#9;&#9;return count &#9;} Is there something else I should do to set the font?
1
0
655
Jul ’20