CFCharacterSet
является бесплатным по мосту с аналогом Cocoa Foundation NSCharacterSet
и может быть подключен к соответствующему типу значения Swift CharacterSet
:
let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
Тогда подход из NSArray из NSCharacterSet может быть использован для перечисления всех скалярных значений Unicode этого набора символов (включая точки, отличные от BMP, т.е. скалярные значения Unicode, превышающие U + FFFF).
CTFontGetGlyphsForCharacters()
ожидает символы не-BMP в качестве суррогатной пары, то есть в виде массива кодовых единиц UTF-16.
Если сложить все вместе, функция будет выглядеть так:
func createUnicodeFontMap(ctFont: CTFont) -> [CGGlyph : UnicodeScalar] {
let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
var glyphToUnicode = [CGGlyph : UnicodeScalar]() // Start with empty map.
// Enumerate all Unicode scalar values from the character set:
for plane: UInt8 in 0...16 where charset.hasMember(inPlane: plane) {
for unicode in UTF32Char(plane) << 16 ..< UTF32Char(plane + 1) << 16 {
if let uniChar = UnicodeScalar(unicode), charset.contains(uniChar) {
// Get glyph for this `uniChar` ...
let utf16 = Array(uniChar.utf16)
var glyphs = [CGGlyph](repeating: 0, count: utf16.count)
if CTFontGetGlyphsForCharacters(ctFont, utf16, &glyphs, utf16.count) {
// ... and add it to the map.
glyphToUnicode[glyphs[0]] = uniChar
}
}
}
}
return glyphToUnicode
}