在Swift中,如何使用CTFontCopyCharacterSet()
获取字体的所有字符? ...对于macOS?
在Swift中通过OSX: CGGlyph to UniChar答案实现方法时,就会发生此问题。
func createUnicodeFontMap() {
// Get all characters of the font with CTFontCopyCharacterSet().
let cfCharacterSet: CFCharacterSet = CTFontCopyCharacterSet(ctFont)
//
let cfCharacterSetStr = "\(cfCharacterSet)"
print("CFCharacterSet: \(cfCharacterSet)")
// Map all Unicode characters to corresponding glyphs
var unichars = [UniChar](…NYI…) // NYI: lacking unichars for CFCharacterSet
var glyphs = [CGGlyph](repeating: 0, count: unichars.count)
guard CTFontGetGlyphsForCharacters(
ctFont, // font: CTFont
&unichars, // characters: UnsafePointer<UniChar>
&glyphs, // UnsafeMutablePointer<CGGlyph>
unichars.count // count: CFIndex
)
else {
return
}
// For each Unicode character and its glyph,
// store the mapping glyph -> Unicode in a dictionary.
// ... NYI
}
使用CFCharacterSet
来检索实际字符的方法已难以捉摸。 cfCharacterSet
实例的自动补全功能不会显示任何相关方法。
然后出现Core Foundation > CFCharacterSet的方法具有创建另一个CFCharacterSet的方法,但是不提供提供单字符数组| list以便创建映射字典的方法。
注意:我正在寻找一个不特定于iOS的解决方案,例如使用UIFont
的{{3}}。
答案 0 :(得分:1)
您可以执行以下操作。
let cs = CTFontCopyCharacterSet(font) as NSCharacterSet
let bitmapRepresentation = cs.bitmapRepresentation
定义了位图的格式
答案 1 :(得分:1)
CFCharacterSet
与Cocoa Foundation的同行NSCharacterSet
之间是免费的桥接,并且可以桥接到相应的Swift值类型CharacterSet
:
let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
然后可以使用NSArray from NSCharacterSet中的方法来枚举该字符集的所有Unicode标量值(包括非BMP点,即大于U + FFFF的Unicode标量值)。
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
}