【问题标题】:Determine if unicode character has a glyph in UIFont确定 unicode 字符是否在 UIFont 中具有字形
【发布时间】:2017-07-21 07:05:23
【问题描述】:

我想知道某个 unicode 字符是否有字形表示,即使是级联字体也是如此。例如,假设我正在使用UIFont.systemFont(withSize:18) 和一个字符串\u{1CDA} 并想知道这个字体是否会显示这个字符的图形表示,而不是默认的问号表示(即没有图形表示,即使由支持的级联字体)。

【问题讨论】:

  • @MartinR 为什么不用你的锤子?
  • @JAL:因为我自己没有解决这个问题的经验。一旦得到 OP 或其他人的确认,我就会欺骗它。
  • @MartinR 我看到了这个问题并正在使用它的解决方案,但它只返回该特定字体的字形。

标签: ios swift unicode uifont ctfont


【解决方案1】:

这对我有用。 Swift 3、XCode 8.6 版本:

import UIKit
import CoreText

extension Font {
    public func hasGlyph(utf32 character:UInt32) -> Bool {

        var code_point: [UniChar] = [
            UniChar.init(truncatingBitPattern: character),
            UniChar.init(truncatingBitPattern: character >> 16)
        ]
        var glyphs: [CGGlyph] = [0,0]
        let result = CTFontGetGlyphsForCharacters(self as CTFont, &code_point, &glyphs, glyphs.count)
        return result
    }
}

public class Glypher {

    let font:UIFont

    var support:[CTFont] = []

    public init(for font:UIFont, languages:[String] = ["en"]) {
        self.font = font
        let languages = languages as CFArray
        let result = CTFontCopyDefaultCascadeListForLanguages(font as CTFont, languages)
        let array = result as! Array<CTFontDescriptor>
        for descriptor in array {
            support.append(CTFontCreateWithFontDescriptor(descriptor,18,nil))
        }
    }

    public func isGlyph(_ point:UInt32) -> Bool {
        return font.hasGlyph(utf32:point) || isGlyphSupported(point)
    }

    public func isGlyphSupported(_ point:UInt32) -> Bool {
        for font in support {
            var code_point: [UniChar] = [
                UniChar.init(truncatingBitPattern: point),
                UniChar.init(truncatingBitPattern: point >> 16)
            ]
            var glyphs: [CGGlyph] = [0, 0]
            let result = CTFontGetGlyphsForCharacters(font as CTFont, &code_point, &glyphs, glyphs.count)
            if result {
                return true
            }
        }
        return false
    }
}

let glypher = Glypher(for:UIFont.systemFont(ofSize:18))
if glypher.isGlyph(0x1CDA) {
    print("bingo!")
}

【讨论】:

  • 当使用 Ingra-Book 和 iPhone 7 模拟器测试此代码时,CTFontGetGlyphsForCharacters 对 UTF-8 BMP 空间中的许多测试用例返回 false。该字体有 1628 个字形 (CTFontGetGlyphCount)。备份支持字体用于所有匹配。字体不能真正安装吗? Swift 3.1、Xcode 8.3.3.、iPhone 7 模拟器。任何建议都会有所帮助。
【解决方案2】:

这也可以,它不检查字形,但它检查字符集

import CoreText
func isSupported(unicode: UnicodeScalar, font: UIFont) -> Bool {
    let coreFont: CTFont = font
    let characterSet: CharacterSet = CTFontCopyCharacterSet(coreFont) as CharacterSet
    return characterSet.contains(unicode)
 }

示例测试:

let testString = "R"
let font = UIFont.boldSystemFont(ofSize: 10.0)
print("\(isSupported(unicode: testString.unicodeScalars.first!, font: font))")

【讨论】:

    猜你喜欢
    • 2014-04-26
    • 2012-11-27
    • 2019-12-18
    • 1970-01-01
    • 2019-06-04
    • 2015-04-30
    • 2010-09-11
    • 1970-01-01
    相关资源
    最近更新 更多