首页 > 解决方案 > Core Text 使用 Swift 在 iOS 中计算字母和 ruby​​ 注释帧

问题描述

如何在 iOS 中由 CoreText 和 CoreGraphics 呈现的 CTFrame 文本中获取每个 ruby​​ 注释字符(或假名)的边界框?(iOS 11、12 或 13)

在此处输入图像描述

基于这个问题Core Text calculate letter frame in iOS我制作了一个快速版本的程序,将每个字符括在一个红色框中,但我无法获得 ruby​​ 注释字符的边界框也就是 furigana。出于这个问题的目的,我将红宝石字符框涂成绿色。

我怎样才能做到这一点?有任何想法吗?

编辑:为清楚起见,绿色框是在插图软件中手工绘制的。我需要通过代码绘制绿色框。

完整源码在 GitHub https://github.com/huse360/LetterFrame 这是主要源码:

 override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
   
    
       context.textMatrix = .identity
       context.translateBy(x: 0, y: self.bounds.size.height)
       context.scaleBy(x: 1.0, y: -1.0)
   
    
       let string = "|優勝《ゆうしょう》の|懸《か》かった|試合《しあい》。|Test《テスト》.\nThe quick brown fox jumps over the lazy dog. 12354567890 @#-+"

    
       let attributedString = Utility.sharedInstance.furigana(String: string)
   
       let range = attributedString.mutableString.range(of: attributedString.string)

       attributedString.addAttribute(.font, value: font, range: range)

   
       let framesetter = attributedString.framesetter()
   
       let textBounds = self.bounds.insetBy(dx: 20, dy: 20)
       let frame = framesetter.createFrame(textBounds)
    
//Draw the frame text:
   
       frame.draw(in: context)
           
       let origins = frame.lineOrigins()
   
       let lines = frame.lines()

        context.setStrokeColor(UIColor.red.cgColor)
        context.setLineWidth(0.7)

        for i in 0 ..< origins.count {

            let line = lines[i]
         
            for run in line.glyphRuns() {
            
                let font = run.font
                let glyphPositions = run.glyphPositions()
                let glyphs = run.glyphs()
            
                let glyphsBoundingRects =  font.boundingRects(of: glyphs)
            
//DRAW the bounding box for each glyph:
            
                for k in 0 ..< glyphPositions.count {
                    let point = glyphPositions[k]
                    let gRect = glyphsBoundingRects [k]
            
                    var box = gRect
                    box.origin +=  point + origins[i] + textBounds.origin
                    context.stroke(box)
                        
                }// for k
        
            }//for run
        
       }//for i
    
    }//func draw

标签: iosswiftcharacterbounding-boxcore-text

解决方案


推荐阅读