首页 > 解决方案 > 核心文本( swift ):为每个字母设置框架

问题描述

归档以下效果时:

888

所以每一个中文字母都是一个CTLine

那么关键的数学问题是计算背景图像/字母的来源

     let bgGrip = UIImage(named: "x")
    
    
     func drawGrips(m info: TxtRenderInfo, lnH lnHeight: CGFloat, index i: Int, dB beginIdx: Int, lineOrigin lnOrigin: CGPoint, context ctx: CGContext, lnAscent lineAscent: CGFloat) -> CGFloat{
            let content = info.strArr[i - beginIdx]
            let glyphCount = content.count
            var frameImg = TextContentConst.bgImgFrame
            let lnOffsset = (TextContentConst.padding - lnHeight) * 0.5
            var lineOrigin = lnOrigin
            lineOrigin.y -= lnOffsset
            var textP = lineOrigin
            for idx in 0..<glyphCount{
                  let pieX = String(content[idx])
                  let ln = CTLineCreateWithAttributedString(pieX.word)
                  let lnSize = ln.lnSize
                  let typeOriginX = TextContentConst.padding * CGFloat(idx + 1)
                  textP.x = typeOriginX + (TextContentConst.padding - lnSize.width) * 0.5
                  ctx.textPosition = textP
                  frameImg.origin.x = typeOriginX
                  frameImg.origin.y = lineOrigin.y + lineAscent - TextContentConst.bgImgFrame.size.height + TextContentConst.offsetP.y
                  // draw image
                  bgGrip?.draw(in: frameImg)
                  // draw text
                  CTLineDraw(ln, ctx)
            }
            return lnOffsset
        }
    
    extension CTLine{
        var lnSize: CGSize{
            var lnAscent:CGFloat      = 0
            var lnDescent:CGFloat     = 0
            var lnLeading:CGFloat     = 0
            let glyphW = CTLineGetTypographicBounds(self , &lnAscent, &lnDescent, &lnLeading)
            let lnHeight = lnAscent + lnDescent + lnLeading
            return CGSize(width: CGFloat(glyphW), height: lnHeight)
        }
    }

CTLine-> CTRun->CGGlyph

一个中文字母是一个CTLine不太好听

那么如何改进代码呢?

github 仓库

标签: iosswiftcore-text

解决方案


推荐阅读