API是否支持这个?如果不是,我该怎么做?如何在iOS中创建多行字符串或多行标签作为CGPath?
Core Text中有CTFontCreatePathForGlyph
,它可以将单个字符转换为路径。我可以在循环中使用它来创建我的字符串作为路径,但是我不得不处理间距和字距问题以及所有其他令人讨厌的事情。我正在寻找一个字符串路径,如果它在具有相同字体和大小的UILabel中绘制,看起来是相同的。
API是否支持这个?如果不是,我该怎么做?如何在iOS中创建多行字符串或多行标签作为CGPath?
Core Text中有CTFontCreatePathForGlyph
,它可以将单个字符转换为路径。我可以在循环中使用它来创建我的字符串作为路径,但是我不得不处理间距和字距问题以及所有其他令人讨厌的事情。我正在寻找一个字符串路径,如果它在具有相同字体和大小的UILabel中绘制,看起来是相同的。
有一篇名为Low-level text rendering的文章Ohmu涵盖了这个相当广泛。我试过这段代码,可以确认它的工作原理。
它确实使用了Core Text,所以渲染可能不完全像UILabel
那样。此外,示例文章只处理一行。要将其扩展为多行,您必须设置完整的Core Text系统。相反的:
CTLineRef line = CTLineCreateWithAttributedString(attStr) ;
你需要建立一个CTFramesetterRef
(CTFramesetterCreateWithAttributedString
)和CTFrameRef
(CTFramesetterCreateFrame
)作为核心文本编程指南描述。然后您可以使用CTFrameGetLines()
获取帧中的所有行。与其他环
CFArrayRef runArray = CTLineGetGlyphRuns(line);
// for each RUN
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
,超过所有行迭代:
你会再包装样品文章中for
循环。循环的内核应该是相同的。
样品文章创建一个图形上下文并添加路径为单字形这种情况下的路径,但你可以很容易地创建一个CGMutablePathRef
或UIBezierPath
和单个字形的路径添加到该对象。
有一件事情没有100%清楚,我没有测试这是如何调整最终路径中字形的垂直位置。您可能需要拨打CTFrameGetLineOrigins()
来获取每行的位置,并将这个位置添加到每个渲染字形(可能在用文本矩阵变换之后)。
查看此项目中的UIBezierPath + TextPaths类别:https://github.com/aderussell/string-to-CGPathRef。
它显示了如何为单行和多行字符串创建路径以及如何将它们与CAShapeLayers一起使用。
该类别只是一个包装,内部函数可以在iOS或Mac OS X中使用,您只需将您的项目链接到CoreText框架即可。
工程就像一个魅力! – CoderSaru
我走过那段代码,但找不到可以访问各个字形的部分,以便构建字形的多行路径。 – openfrog
你是对的,该代码只处理一行文本。我将编辑我的答案以扩展它(可能需要一些时间)。 –
我编辑了我的答案,给你一些更多的想法。 –