如何在iOS中获取表情符号路径

时间:2017-02-14 17:00:52

标签: ios swift uibezierpath core-text

我的目的:绘制每个字形的轮廓

例1:

输入: text= "666棒"

显示:
enter image description here

附加:在上图中,1是displayView,2是inputView。

例2:

输入text= "666棒"

显示
enter image description here

附加:在上图中,1为displayView,2为inputView,3为无渲染。

主要观点是:

  1. 使用每个CGglyph获得的CoreText。
  2. 获取每个字形的CGPath
  3. 使用CAShapeLayer在屏幕上显示字形。
  4. 主要方法:

        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)
       ...
    

    问题:

    如何获取表情符号路径,在这种情况下我可以绘制表情符号轮廓而不是绘制整个表情符号?另一个好处是,如果需要,我可以绘制动画表情符号。

    感谢任何帮助!

    ************************更新2.15.2017 ******************* ****

    感谢@KrishnaCA的建议。

    我使用bool supports = CTFontGetGlyphWithName(myFont, "")发现没有字体支持表情符号。

    幸运的是 Google的Noto 为表情符号字体提供了很好的支持

    你可以在那里找到它:google's Noto

    我使用了字体 Noto Emoji

    显示:

    enter image description here

    只有 Noto Emoji Noto Color Emoji 支持表情符号(我猜)

    希望能帮到那些来这里的人!

3 个答案:

答案 0 :(得分:1)

我相信您需要检查是否存在与CTFont对应的unicode的字形。如果它不存在,则回退到任何具有unicode glpyh的默认CTFont

您可以使用以下代码进行检查。

bool supports = CTFontGetGlyphWithName(myFont, "")

这里,myFont是一个CTFontRef对象。

如果您不是在寻找

,请告诉我

答案 1 :(得分:0)

我相信您需要CATextLayers来帮助您。

答案 2 :(得分:0)

我知道这有点晚了,但是遗憾的是你不能-表情符号实际上是与表示常规字符的形状绘制在同一上下文中的位图。最好的选择可能是根据需要的比例分别将表情符号字符绘制到上下文中。这将使您无法访问实际的矢量数据。

如果您真的需要矢量形式的

  • 我会去寻找在矢量中重新绘制的Apple Emoji字体(我记得在互联网上看到过,虽然不确定它是否包含所有最新的emoji表情)
  • 将找到的单个矢量图像的名称映射到字符上,然后绘制矢量图像