Core Text calculate letter AND ruby annotation frames in iOS with Swift

How can I get the bounding box for each ruby annotation character (or furigana) in a CTFrame text rendered by CoreText and CoreGraphics in iOS? (iOS 11, 12 or 13)


I made a swift version program that encloses each character in a red box but I wasn't able to get the bounding boxes for the ruby annotation characters, *aka furigana*. I painted in green the ruby character boxes for the purpose of this question. (Please see the image in the GitHub link)

How can I achieve that? Any Ideas?

Edit: For clarity, the green boxes were painted by hand in an illustration software. I need to draw the green boxes by code.

The full source is in GitHub https://github.com/huse360/LetterFrame
This is the main source code:

Code Block
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




The information for the Ruby annotations is not currently exposed through Core Text API. Please file a new feedback under Core Text API to request that.
Core Text calculate letter AND ruby annotation frames in iOS with Swift
 
 
Q