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:
Here is the text render when the text count is too big above 10kb, it appears disjointed and reversed:
Arabic text must be typeset to reflect this: text that is left aligned in English should generally become right aligned in Arabic. In fact, the whole layout must reflect this directionality. In a 3 column page of Arabic text, the first column starts at the top right of the page.
A line of English text starts at the left-hand side and is read from the left to the right. Arabic runs in the other direction: the text starts on the right-hand side of the line and reads on to the left. Arabic text must be typeset to reflect this: text that is left aligned in English should generally become right aligned in Arabic.
Arabic runs in the other direction: the text starts on the right-hand side of the line and reads on to the left. Arabic text must be typeset to reflect this: text that is left aligned in English should generally become right aligned in Arabic. In fact, the whole layout must reflect this directionality.
Yet, for those used to other languages, Arabic typesetting contains some stumbling blocks. A line of English text starts at the left-hand side and is read from the left to the right. Arabic runs in the other direction: the text starts on the right-hand side of the line and reads on to the left.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With