iosswiftcore-textarabic-support

CoreText With Too Long Arabic Text


I was trying to follow a tutorial on CoreText and how to draw the text, and I implemented this function in my customView.

override func draw(_ rect: CGRect) {         
 guard let context = UIGraphicsGetCurrentContext() else { return }       
 let path = CGMutablePath()
 path.addRect(bounds)
 let attrString = NSAttributedString(string: "Hello World")
 let framesetter = CTFramesetterCreateWithAttributedString(attrString as CFAttributedString)
 let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attrString.length), path, nil) 
 CTFrameDraw(frame, context)
}

It works fine when the text is short but when the text becomes more than 10k letters, it renders in a wrong way. Is there any solution for that?

NOTE: this happen when the text in Arabic not English.

Here is the render when the text is small: enter image description here

Here is the text render when the text count is too big above 10kb, it appears disjointed and reversed:

enter image description here


Solution

  • Based on your feedback from Apple, it seems that CTFramesetter turns off advanced layout when the string is longer than a certain size. (Their suggestion that this is because there is mixed-direction text doesn't sound right; I've definitely reproduced this with only Arabic.)

    To fix this, you need to create a framesetter with a custom typesetter that always does advanced layout (kCTTypesetterOptionAllowUnboundedLayout). Luckily that's straightforward.

    Create a custom typesetter first, and then use that to create the framesetter:

    let typesetterOptions = [kCTTypesetterOptionAllowUnboundedLayout: true] as CFDictionary
    let typesetter = CTTypesetterCreateWithAttributedStringAndOptions(attrString,
                                                                      typesetterOptions)!
    let framesetter = CTFramesetterCreateWithTypesetter(typesetter)