swift - 确定可移植 Swift 中的字符串边界框?

标签 swift fonts

如何在可移植 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])

应用说明:这个问题是能够在 Swift 生成的 SVG 文件中布局文本字符串的总体目标的一部分。

最佳答案

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)]

关于swift - 确定可移植 Swift 中的字符串边界框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56548870/

相关文章:

c# - 为什么 Font 是不可变的?

ios - 由于错误代码 1580,Swift Coredata 无法保存

json - swift/Alamofire : Iterating through JSON values to check for bool value?

java - AndroidBoostrap预览模式: Font not properly registered

javascript - 标题按钮的文本/字体粗细无意中改变

css - 将 @font-face 与 Web 控件库中嵌入的字体一起使用

java - 使用 PDFBox 填写表单时如何替换丢失的字体?

像 Swift 一样使用 Enum 进行 Objective-C 错误处理

ios - 使用 tableViewController 时 iphone x home 指示器问题

ios - 编程 UITableView 的 didSelectRowAtIndexPath 不响应触摸