检测何时无法正确显示 unicode 字符
Detect when a unicode character cannot be displayed correctly
有些 unicode 字符无法在 iOS 上显示,但在 macOS 上可以正确显示。同样,一些iOS可以显示的unicode字符在watchOS上无法显示。这是因为这些平台安装的内置字体不同。
当无法显示字符时,它显示为 ?在一个盒子里,像这样:
我也看到一些角色显示为外星人(不知道为什么不同):
有没有办法知道特定的 unicode 字符何时无法正确显示给定的 unicode 字符字符串,例如 "ᄥ"
?
我需要一个适用于 iOS 和 watchOS 的解决方案。
您可以使用 CTFontGetGlyphsForCharacters()
来确定字体是否具有特定代码点的字形(请注意,补充字符需要作为代理项对进行检查):
CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica"), 12, NULL);
const UniChar code_point[] = { 0xD83C, 0xDCA1 }; // U+1F0A1
CGGlyph glyph[] = { 0, 0 };
bool has_glyph = CTFontGetGlyphsForCharacters(font, code_point, glyph, 2);
或者,在 Swift 中:
let font = CTFontCreateWithName("Helvetica", 12, nil)
var code_point: [UniChar] = [0xD83C, 0xDCA1]
var glyphs: [CGGlyph] = [0, 0]
let has_glyph = CTFontGetGlyphsForCharacters(font, &code_point, &glyph, 2)
如果要检查系统将尝试从中加载字形的完整后备字体集,则需要检查 CTFontCopyDefaultCascadeListForLanguages()
返回的所有字体。查看 以了解有关如何创建后备字体列表的信息。
与已知的未定义字符进行比较 U+1FFF
:
/// - Parameter font: a UIFont
/// - Returns: true if glyph exists
func glyphAvailable(forFont font:UIFont) -> Bool {
if let refUnicodePng = Character("\u{1fff}").png(forFont: font),
let myPng = self.png(forFont: font) {
return refUnicodePng != myPng
}
return false
}
使用 png 位图:
/// - Parameter font: a UIFont
/// - Returns: an optional png representation
func png(forFont font: UIFont) -> Data? {
let attributes = [NSAttributedStringKey.font: font]
let charStr = "\(self)" as NSString
let size = charStr.size(withAttributes: attributes)
UIGraphicsBeginImageContext(size)
charStr.draw(at: CGPoint(x: 0,y :0), withAttributes: attributes)
var png:Data? = nil
if let charImage = UIGraphicsGetImageFromCurrentImageContext() {
png = UIImagePNGRepresentation(charImage)
}
UIGraphicsEndImageContext()
return png
}
已回答 。
有些 unicode 字符无法在 iOS 上显示,但在 macOS 上可以正确显示。同样,一些iOS可以显示的unicode字符在watchOS上无法显示。这是因为这些平台安装的内置字体不同。
当无法显示字符时,它显示为 ?在一个盒子里,像这样:
我也看到一些角色显示为外星人(不知道为什么不同):
有没有办法知道特定的 unicode 字符何时无法正确显示给定的 unicode 字符字符串,例如 "ᄥ"
?
我需要一个适用于 iOS 和 watchOS 的解决方案。
您可以使用 CTFontGetGlyphsForCharacters()
来确定字体是否具有特定代码点的字形(请注意,补充字符需要作为代理项对进行检查):
CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica"), 12, NULL);
const UniChar code_point[] = { 0xD83C, 0xDCA1 }; // U+1F0A1
CGGlyph glyph[] = { 0, 0 };
bool has_glyph = CTFontGetGlyphsForCharacters(font, code_point, glyph, 2);
或者,在 Swift 中:
let font = CTFontCreateWithName("Helvetica", 12, nil)
var code_point: [UniChar] = [0xD83C, 0xDCA1]
var glyphs: [CGGlyph] = [0, 0]
let has_glyph = CTFontGetGlyphsForCharacters(font, &code_point, &glyph, 2)
如果要检查系统将尝试从中加载字形的完整后备字体集,则需要检查 CTFontCopyDefaultCascadeListForLanguages()
返回的所有字体。查看
与已知的未定义字符进行比较 U+1FFF
:
/// - Parameter font: a UIFont
/// - Returns: true if glyph exists
func glyphAvailable(forFont font:UIFont) -> Bool {
if let refUnicodePng = Character("\u{1fff}").png(forFont: font),
let myPng = self.png(forFont: font) {
return refUnicodePng != myPng
}
return false
}
使用 png 位图:
/// - Parameter font: a UIFont
/// - Returns: an optional png representation
func png(forFont font: UIFont) -> Data? {
let attributes = [NSAttributedStringKey.font: font]
let charStr = "\(self)" as NSString
let size = charStr.size(withAttributes: attributes)
UIGraphicsBeginImageContext(size)
charStr.draw(at: CGPoint(x: 0,y :0), withAttributes: attributes)
var png:Data? = nil
if let charImage = UIGraphicsGetImageFromCurrentImageContext() {
png = UIImagePNGRepresentation(charImage)
}
UIGraphicsEndImageContext()
return png
}
已回答