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:
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