我的目的:绘制每个字形的轮廓。
示例1:
输入:text = "666棒"
附加说明:上图中,1 是显示视图,2 是输入视图。
示例2:
输入:text = "666棒"
附加说明:上图中,1 是显示视图,2 是输入视图,3 没有渲染。
主要思路:
- 使用 CoreText 获取每个 CGglyph。
- 获取每个字形的 CGPath。
- 使用 CAShapeLayer 在屏幕上显示字形。
主要方法:
let letters = CGMutablePath()
let font = CTFontCreateWithName(fontName as CFString?, fontSize, nil)
let attrString = NSAttributedString(string: text, attributes: [kCTFontAttributeName as String : font])
let line = CTLineCreateWithAttributedString(attrString)
let runArray = CTLineGetGlyphRuns(line)
for runIndex in 0..<CFArrayGetCount(runArray) {
let run : CTRun = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self)
let dictRef : CFDictionary = unsafeBitCast(CTRunGetAttributes(run), to: CFDictionary.self)
let dict : NSDictionary = dictRef as NSDictionary
let runFont = dict[kCTFontAttributeName as String] as! CTFont
for runGlyphIndex in 0..<CTRunGetGlyphCount(run) {
let thisGlyphRange = CFRangeMake(runGlyphIndex, 1)
var glyph = CGGlyph()
var position = CGPoint.zero
CTRunGetGlyphs(run, thisGlyphRange, &glyph)
CTRunGetPositions(run, thisGlyphRange, &position)
let letter = CTFontCreatePathForGlyph(runFont, glyph, nil)
let t = CGAffineTransform(translationX: position.x, y: position.y)
if let letter = letter {
letters.addPath(letter, transform: t)
}
}
}
let path = UIBezierPath()
path.move(to: CGPoint.zero)
path.append(UIBezierPath(cgPath: letters))
let pathLayer = CAShapeLayer()
pathLayer.path = path.cgPath
self.layer.addSubLayer(pathLayer)
...
问题:
如何获取emoji路径,在这种情况下,我可以绘制emoji轮廓而不是绘制整个emoji?另一个好处是如果需要,我可以绘制动画的emoji路径。
非常感谢任何帮助!
************************ 更新 2017.2.15 ***********************
感谢@KrishnaCA的建议。
我使用bool supports = CTFontGetGlyphWithName(myFont, "")
发现没有字体支持emoji。
幸运的是Google的Noto为emoji字体提供了良好的支持。
您可以在此处找到它:Google的Noto
我使用的字体是Noto Emoji
显示:
只有Noto Emoji和Noto Color Emoji支持Emoji(我猜)
希望能帮助来到这里的人们!