获取跟踪iOS UIFont中的角色的路径

Joe*_*oel 17 iphone core-graphics uifont cgpath ios

假设我在我的iOS应用程序中使用了自定义字体"Foo".我已将它添加到我的项目,plist等等,我可以UILabel用它来渲染s等等.

现在,如果我想找出一系列能够"追踪"该字体中的字母"P"的点,我将如何获得该点序列?例如,假设我想用a CGPath来绘制字母'P',就像绘图仪一样......

我只需要一个CGPoints数组中的序列,如果绘制为路径将绘制一个'P'.

我意识到对于像'T'这样的字母,这可能没有意义,因为笔必须被提升以越过'T'.所以也许我需要一系列CGPath的...

有关如何实现这一目标的任何提示?

谢谢!

rob*_*off 35

从字母"P"到一系列点包括几个步骤.您需要使用Core Text.

  1. 创建一个CTFont.由于iOS的7,您可以使用UIFont其中一个CTFont需要(他们是"免费桥接").您也可以CTFont直接从CGFont使用CTFontCreateWithGraphicsFont函数创建,或使用名称CTFontCreateWithName(或使用其他一些方法)创建.

  2. 使用该CTFontGetGlyphsForCharacters函数获取字母的字形.对于字母"P",应该只有一个字形.对于非英语脚本中的某些字符,您可能会获得多个(组合)字形.

  3. 使用该CTFontCreatePathForGlyph函数获取CGPath字形.

  4. 使用CGPathApply枚举路径的元素.

  5. 将路径的每条线,四条曲线和三次曲线元素转换为一系列点.Apple没有为此提供任何公共API.你需要自己做.对于直线元素,它很容易.对于曲线元素,如果您还不知道如何渲染Bézier曲线,则需要进行一些研究.例如,请参见将贝塞尔曲线转换为多边形链?.

我们可以在Swift游乐场轻松地进行实验:

import UIKit
import CoreText
import XCPlayground

let font = UIFont(name: "HelveticaNeue", size: 64)!

var unichars = [UniChar]("P".utf16)
var glyphs = [CGGlyph](count: unichars.count, repeatedValue: 0)
let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count)
if gotGlyphs {
    let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)!
    let path = UIBezierPath(CGPath: cgpath)
    print(path)
    XCPlaygroundPage.currentPage.captureValue(path, withIdentifier: "glyph \(glyphs[0])")
}
Run Code Online (Sandbox Code Playgroud)

结果:

<UIBezierPath: 0x7fbc89e0d370; <MoveTo {11.072000000000001, 23.808}>,
 <LineTo {11.072000000000001, 40.576000000000001}>,
 <LineTo {22.975999999999999, 40.576000000000001}>,
 <QuadCurveTo {30.560000000000002, 38.432000000000002} - {28.16, 40.576000000000001}>,
 <QuadCurveTo {32.960000000000001, 32.192} - {32.960000000000001, 36.288000000000004}>,
 <QuadCurveTo {30.560000000000002, 25.920000000000002} - {32.960000000000001, 28.096}>,
 <QuadCurveTo {22.975999999999999, 23.808} - {28.16, 23.744}>,
 <Close>,
 <MoveTo {4.992, 45.695999999999998}>,
 <LineTo {4.992, 0}>,
 <LineTo {11.072000000000001, 0}>,
 <LineTo {11.072000000000001, 18.687999999999999}>,
 <LineTo {25.024000000000001, 18.687999999999999}>,
 <QuadCurveTo {35.488, 22.208000000000002} - {31.936, 18.623999999999999}>,
 <QuadCurveTo {39.039999999999999, 32.192} - {39.039999999999999, 25.792000000000002}>,
 <QuadCurveTo {35.488, 42.143999999999998} - {39.039999999999999, 38.591999999999999}>,
 <QuadCurveTo {25.024000000000001, 45.695999999999998} - {31.936, 45.695999999999998}>,
 <Close>
Run Code Online (Sandbox Code Playgroud)

P字形路径