如何在便携式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文件中布局文本字符串。
答案 0 :(得分:0)
快速
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)]