Skip navigation.
 
mlRe: NSTextView and layout manager speed (was: how to be efficient)
FROM : Keith Blount
DATE : Thu Apr 28 17:44:01 2005

Thanks again for your reply. I ran Sampler, and all
it's really telling me is that the NSLayoutManager
calls are slowing things down (lots of private
NSLayoutManager and typesetter methods to do with
laying out the text). I've pasted my methods that call
the layout manager methods during load below, in case
anybody can suggest a way of doing it faster. The
slowdown happens when there are a lot of notes that
need loading in the margin of a document - for
instance, with a document that has 200 notes, these
methods have to be called 200 times when the document
loads. On my G4 1Ghz, it takes 3 seconds to load a
document with 200 notes, so maybe that isn't so slow,
but if there is a way of getting them faster, I would
love to find it.

Many thanks again, and thanks in advance to anybody
else who can offer any advice on speeding up these
methods.

All the best,
Keith

- (float)verticalPositionOfCharacter:(int)charIndex
{
   NSLayoutManager *layoutManager = [owner
layoutManager];
   NSPoint containerOrigin = [owner
textContainerOrigin];
   float vertPos = 0;
   
   int glyphIndex = [layoutManager
glyphRangeForCharacterRange:NSMakeRange(charIndex,1)
                                         actualCharacterRange:NULL].location;
   
   // If there is no valid character at the index we
must be at the beginning of the text view,
   // and there must be no text in the text view
(because we adjust for this in textDidChange:),
   // so we will keep vertPos as zero
   if ([layoutManager isValidGlyphIndex:glyphIndex])
   {
       // First get the rect of the line the character is
in
       vertPos = [layoutManager
lineFragmentUsedRectForGlyphAtIndex:glyphIndex
effectiveRange:nil].origin.y;
       vertPos += containerOrigin.y;
   }
   
   return vertPos;
}

- (NSSize)sizeWithWidth:(float)width
{   
    if ([string length] > 0)
   {
        NSRange glyphRange;
        NSSize requiredSize;
       
       NSLayoutManager *lm = [[contents layoutManagers]
objectAtIndex:0];
       NSTextContainer *tc = [[lm textContainers]
objectAtIndex:0];
       
       BOOL textChanged = NO;
       if (![[contents string] isEqualToString:string])
       {
           [contents
replaceCharactersInRange:NSMakeRange(0,[contents
length]) withString:string];
           textChanged = YES;
       }
       
       if ( (width != [tc containerSize].width) ||
textChanged )
       {
           [tc setContainerSize:NSMakeSize(width,FLT_MAX)];
       
           // Force layout of the text and find out how much
of it fits in the container
           glyphRange = [lm glyphRangeForTextContainer:tc];
       
           if (glyphRange.length>0)
           {
               requiredSize = [lm
usedRectForTextContainer:tc].size;
               //requiredSize = [lm
boundingRectForGlyphRange:glyphRange
inTextContainer:tc].size;
               requiredSize.width = width;    // Set width
regardless of used rect
               [tc setContainerSize:requiredSize];
           }
       }
       return [tc containerSize];
   }
   return NSZeroSize;
}

> FROM : John Brownlow
> DATE : Wed Apr 27 16:14:36 2005
>
> the next thing to do is run Sampler alongside your
> layout code and see
> what's taking the time.
>
> On Apr 27, 2005, at 5:29 AM, Keith Blount wrote:
>
> Many thanks to both of you for your replies (sorry

it
> has taken a few days to thank you - I've only just

got
> back to this part of my app.)
>
> I have followed your suggestions, and now instead of
> having a simple NSString as an instance variable, my
> note objects have an NSTextStorage. On

initialisation,
> I create a text container and layout manager and

have
> the text storage own these, rather than having to

use
> the shared layout manager. I'm not 100% sure this is
> any faster than using the shared layout manager (the
> shared layout manager was created using the code

from
> the Sketch example), but at least things are faster
> than in my old implementation that used lots of text
> views. A document with 200 notes (and it's highly
> unlikely a real user will ever have as many notes)

now
> loads in about 4-5 seconds, whereas it used to take
> about 8-10. I'd still like to speed things up

further,
> but maybe that's not going to happen on my G4 1Ghz
> machine...


--
John Brownlow
Deep Fried Films, Inc

http://www.johnbrownlow.com
http://www.pinkheadedbug.com

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Related mailsAuthorDate
mlRe: NSTextView and layout manager speed (was: how to be efficient) Keith Blount Apr 28, 17:44
mlRe: NSTextView and layout manager speed (was: how to be efficient) glenn andreas Apr 28, 18:03