Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 986
Bathant Hegazy Avatar asked Dec 14 '20 17:12

Bathant Hegazy


People also ask

What is the best way to format Arabic text?

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.

What is the difference between English and Arabic text?

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.

What is the direction of text 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.

What are the challenges of Arabic Typesetting?

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.


1 Answers

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)
like image 110
Rob Napier Avatar answered Sep 30 '22 11:09

Rob Napier