API 支持吗?如果没有,我该怎么做?
Core Text 中有CTFontCreatePathForGlyph
,可以将单个字符翻译成路径。我可以在循环中使用它来创建我的字符串作为路径,但我必须处理间距和字距调整以及所有其他讨厌的事情。我正在寻找一个字符串路径,如果它是在具有相同字体和大小的 UILabel 中绘制的,它将看起来相同。
API 支持吗?如果没有,我该怎么做?
Core Text 中有CTFontCreatePathForGlyph
,可以将单个字符翻译成路径。我可以在循环中使用它来创建我的字符串作为路径,但我必须处理间距和字距调整以及所有其他讨厌的事情。我正在寻找一个字符串路径,如果它是在具有相同字体和大小的 UILabel 中绘制的,它将看起来相同。
查看此项目中的 UIBezierPath+TextPaths 类别:https ://github.com/aderussell/string-to-CGPathRef 。
它展示了如何为单行和多行字符串创建路径以及如何将它们与 CAShapeLayers 一起使用。
该类别只是一个包装器,内部函数可以在 iOS 或 Mac OS X 中使用,您只需要将您的项目链接到 CoreText 框架。
Ohmu的一篇名为Low-level text rendering的文章非常广泛地涵盖了这一点。我已经尝试过这段代码并且可以确认它有效。
不过,它确实使用了 Core Text,因此渲染可能与UILabel
. 此外,示例文章仅处理一行。要将其扩展到多行,您必须设置完整的核心文本系统。代替:
CTLineRef line = CTLineCreateWithAttributedString( attStr ) ;
您需要按照 Core Text Programming Guide 中的说明设置CTFramesetterRef
( CTFramesetterCreateWithAttributedString
) 和CTFrameRef
( )。CTFramesetterCreateFrame
然后,您可以使用 获取框架中的所有行CTFrameGetLines()
。
然后,您将for
在示例文章中包装循环:
CFArrayRef runArray = CTLineGetGlyphRuns(line);
// for each RUN
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
另一个循环遍历所有行。循环的内核应该是相同的。
示例文章创建了一个图形上下文并将单个字形的路径添加到此上下文的路径中,但您也可以轻松地创建一个CGMutablePathRef
orUIBezierPath
并将单个字形的路径添加到该对象。
如果没有对此进行测试,对我来说不是 100% 清楚的一件事是如何调整最终路径中字形的垂直位置。您可能必须调用CTFrameGetLineOrigins()
以获取每行的位置并将该位置添加到每个呈现的字形(可能在使用文本矩阵对其进行转换之后)。