I’m trying to figure out why some text (seems to be when mixing languages) is so slow to edit in NSTextView. You can reproduce the problem in TextEdit (I’m reproducing it on OS X 10.11.1) with the attached document:
EnglishChineseHebrewGreek.txt (31.0 KB)
-
Open the document in TextEdit
-
Zoom that document’s window to full-screen mode.
-
Type fast in the 16th paragraph where it says “TYPE IN THIS PARAGRAPH”. And notice there’s a noticeable lag when typing. In full screen mode for me it seems there’s a lag most anywhere that I type. If I size the window smaller editing some lines presents a smaller or no lag, while other lines (such as the 16th line) present a noticeable lag.
For any developers who might have an idea of what is causing this I’ve created an example project with some console logging. The underlying problem seems to be that when I type a single character in that paragraph these things happen for each keystroke:
KeyDown
2015-12-08 12:13:16.734 TextTest[71365:32040704] layoutCharactersInRange: {729, 69}
2015-12-08 12:13:16.735 TextTest[71365:32040704] layoutCharactersInRange: {798, 17045}
2015-12-08 12:13:16.736 TextTest[71365:32040704] layoutCharactersInRange: {1370, 16473}
2015-12-08 12:13:16.736 TextTest[71365:32040704] layoutCharactersInRange: {1639, 16204}
2015-12-08 12:13:16.737 TextTest[71365:32040704] layoutCharactersInRange: {1877, 15966}
2015-12-08 12:13:16.738 TextTest[71365:32040704] setFrameSize: {809, 4290}
2015-12-08 12:13:16.738 TextTest[71365:32040704] setNeedsDisplayInRect: rect=self.bounds
2015-12-08 12:13:16.740 TextTest[71365:32040704] layoutCharactersInRange: {2742, 15101}
2015-12-08 12:13:16.740 TextTest[71365:32040704] setFrameSize: {809, 4276}
2015-12-08 12:13:16.740 TextTest[71365:32040704] layoutCharactersInRange: {2535, 207}
2015-12-08 12:13:16.741 TextTest[71365:32040704] layoutCharactersInRange: {2742, 15101}
2015-12-08 12:13:16.741 TextTest[71365:32040704] setFrameSize: {809, 4248}
2015-12-08 12:13:16.744 TextTest[71365:32040704] setNeedsDisplayInRect: rect=self.bounds
2015-12-08 12:13:16.746 TextTest[71365:32040704] layoutCharactersInRange: {3027, 14816}
2015-12-08 12:13:16.746 TextTest[71365:32040704] setFrameSize: {809, 4234}
2015-12-08 12:13:16.746 TextTest[71365:32040704] layoutCharactersInRange: {3215, 14628}
2015-12-08 12:13:16.747 TextTest[71365:32040704] setFrameSize: {809, 4220}
2015-12-08 12:13:16.750 TextTest[71365:32040704] setNeedsDisplayInRect: rect=self.bounds
NSTypesetter method layoutCharactersInRange
is called a bunch with many different and overlapping ranges.
NSTextView’s setFrameSize
method is called multiple times.
And as a result NSTextView is asked to do a full repaint on each keystroke.
Does anyone know why this would be happening, and how I might avoid it?
Here’s the example project with that logging:
TextTest.zip (255.8 KB)