Определить ограничивающую рамку в портативном Swift? - PullRequest
0 голосов
/ 11 июня 2019

Как можно определить ограничивающую рамку для строки, используя определенный шрифт в переносном Swift?

Это кроссплатформенная (Linux, iOS, macOS и т. Д.) Альтернатива текущей платформе UIFont, NSFont подходит?

Пример iOS

import UIKit

let uiFont = UIFont(...)
let nsString = NSString(string: "Hello!")
let boundingBox: CGSize = 
     nsString.size(withAttributes: [NSAttributedString.Key.font: uiFont])

Пример macOS

import Cocoa

let nsFont = NSFont(...)
let nsString = NSString(string: "Hello!")
let boundingBox: NSSize = 
     nsString.size(withAttributes: [NSAttributedString.Key.font: nsFont])

ПриложениеПримечание. Этот вопрос является частью общей цели - иметь возможность размещать текстовые строки в файле SVG, созданном Swift.

1 Ответ

0 голосов
/ 12 июня 2019

Swift

import Foundation

public static func getStringWidth() {
    // PostScript name: DejaVuSansMono
    //       Full name: DejaVu Sans Mono
    //           Style: Book
    //            Kind: OpenType TrueType
    //     Unique name: DejaVu Sans Mono
    let cfsFontName: CFString = "DejaVu Sans Mono" as CFString

    // Use either the font's PostScript name or full name
    guard let cgFont = CGFont(cfsFontName) else {
        return
    }

    let ctFont: CTFont = CTFontCreateWithGraphicsFont(
        cgFont, // graphicsFont: CGFont
        12.0,   // size: CGFloat
        nil,    // matrix: UnsafePointer<CGAffineTransforms>?
        nil     // attributes: CTFontDescriptor?
    )

    let str = "Hello!"

    var unichars = [UniChar](str.utf16)
    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
    }

    let glyphsCount = glyphs.count
    var advances = [CGSize](
        repeating: CGSize(width: 0.0, height: 0.0), 
        count: glyphsCount
    )
    let width = CTFontGetAdvancesForGlyphs(
        ctFont,      // font: CTFont
        CTFontOrientation.horizontal, // orientation: CFFontOrientation
        glyphs,      // glyphs: UnsafePointer<CGGlyph>
        &advances,   // advances: UnsafeMutablePointer<CGSize>?
        glyphsCount // count: CFIndex
    )
    print("width=\(width)")
    print("advances=\(advances)")

    var boundingRects = [CGRect](
        repeating: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.0), 
        count: glyphsCount
    )

    // Result: font design metrics transformed into font space.
    let boundingBox = CTFontGetBoundingRectsForGlyphs(
        ctFont,         // font: CTFont
        .horizontal,    // orientation: CFFontOrientation
        glyphs,         // glyphs: UnsafePointer<CGGlyph>
        &boundingRects, // boundingRects: UnsafeMutablePointer<CGRect>?
        glyphsCount     // count: CFIndex
    )
    print("boundingBox=\(boundingBox)")
    print("boundingRects=\(boundingRects)")
}

Результат

width=43.34765625
advances=[(7.224609375, 0.0), (7.224609375, 0.0), (7.224609375, 0.0), (7.224609375, 0.0), (7.224609375, 0.0), (7.224609375, 0.0)]

boundingBox=(0.720703125, -0.169921875, 5.794921875, 9.3515625)
boundingRects=[(0.802734375, 0.0, 5.619140625, 8.748046875), (0.720703125, -0.169921875, 5.794921875, 6.890625), (0.9375, 0.0, 5.12109375, 9.181640625), (0.9375, 0.0, 5.12109375, 9.181640625), (0.802734375, -0.169921875, 5.619140625, 6.890625), (3.0234375, 0.0, 1.189453125, 8.748046875)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...