Как получить все символы шрифта с помощью CTFontCopyCharacterSet () в Swift?

Как получить все символы шрифта с помощью CTFontCopyCharacterSet() в Swift? ... для macOS?

Проблема возникла при реализации подхода от ответа OSX: CGGlyph к UniChar в Swift.

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
        &glyphs, // UnsafeMutablePointer
        unichars.count // count: CFIndex
        )
        else {
            return
    }

    // For each Unicode character and its glyph, 
    // store the mapping glyph -> Unicode in a dictionary.
    // ... NYI
}

Что делать с CFCharacterSet для получения фактических символов, было неуловимо. Автозаполнение экземпляров cfCharacterSet не показывает релевантных методов.

enter image description here

И у Core Foundation> CFCharacterSet есть методы для создания другого CFCharacterSet, но не то, что предоставляет массив | list | строка unichars, чтобы иметь возможность создать сопоставленный словарь.


Примечание. Я ищу решение, не относящееся к iOS, как в . Получите все доступные символы из шрифта , который использует UIFont.

1
задан l --marc l 27 June 2019 в 21:26
поделиться

2 ответа

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
}
1
ответ дан Martin R 27 June 2019 в 21:26
поделиться

Вы можете сделать что-то вроде этого.

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

Формат растрового изображения определен на странице ссылки для CFCharacterSetCreateWithBitmapRepresentation

1
ответ дан idz 27 June 2019 в 21:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: