How to get all characters of the font with CTFontCopyCharacterSet() in Swift?

前端 未结 2 1262
清歌不尽
清歌不尽 2021-01-27 00:51

How does one get all characters of the font with CTFontCopyCharacterSet() in Swift? ... for macOS?

The issue occured when implementing the approach from an

相关标签:
2条回答
  • 2021-01-27 01:35

    You can do something like this.

    let cs = CTFontCopyCharacterSet(font) as NSCharacterSet
    let bitmapRepresentation = cs.bitmapRepresentation
    

    The format of the bitmap is defined in the reference page for CFCharacterSetCreateWithBitmapRepresentation

    0 讨论(0)
  • 2021-01-27 01:41

    CFCharacterSet is toll-free bridged with the Cocoa Foundation counterpart NSCharacterSet, and can be bridged to the corresponding Swift value type CharacterSet:

    let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
    

    Then the approach from NSArray from NSCharacterSet can be used to enumerate all Unicode scalar values of that character set (including non-BMP points, i.e. Unicode scalar values greater than U+FFFF).

    The CTFontGetGlyphsForCharacters() expects non-BMP characters as surrogate pair, i.e. as an array of UTF-16 code units.

    Putting it together, the function would look like this:

    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
    }
    
    0 讨论(0)
提交回复
热议问题