Probelm with NSLayoutManager notifications
Probelm with NSLayoutManager notifications
- Subject: Probelm with NSLayoutManager notifications
- From: Brock Brandenberg <email@hidden>
- Date: Mon, 22 Apr 2002 11:20:22 -0500
I have an NSView subclass that I am doing glyph drawing in. I'm
instancing the usual NSTextStorage, NSLayoutManager and NSTextContainer
in the NSView subclass to do the attributed string storage and glyph
generation, then I'm using CGContextShowGlyphsAtPoint to draw the glyphs
in the view. I am extracting metrics from the glyphs and supplying them
to other functions which are using the metrics to resize the NSView to
the bounding rect of the glyphs and to determine where the NSView will
be drawn its superview. The attributed string of the NSTextStorage is
getting changed often, and I'm using the appropriate beginEditing:,
replaceCharactersInRange:, setAttributes: and endEditing: on the
NSTextStorage to do so. As a result, NSTextStorage is sending the
appropriate notifications to the NSLayoutManager to cause glyph
regeneration.
My problem is this. I need to catch the NSLayoutManager after this gylph
regeneration to extract the new glyph metrics to supply to my other
functions to do the resizing and moving of the NSView, and I would like
to use a notification like layoutManagerDidInvalidateLayout: to do so.
However, the function that I use to extract the glyph metrics causes
another glyph regeneration (when the NSLayoutManager should be probably
be using cached info, according to the docs), so I get the usual
infinite loop of notification, call, notification, call, etc. I am
currently manually calling my function to get the gylph metrics after I
update the NSTextStorage, and it works, but I feel that I could do it in
a cleaner way using NSLayoutManager notifications.
FYI, the function that gets the glyph metrics uses the following logic.
It's an incomplete code sample, but you can see that I'm getting the
real bounding rect for each valid glyph relative to the first glyph.
This is critical to us because we need the entire glyph to be drawn and
NSTextView and other text drawing functions tend to screw up and clip
glyphs like the "f" in Zapfino.
glyphRange = [refLayoutManager
glyphRangeForTextContainer:refTextContainer];
for( i=glyphRange.location; i<NSMaxRange(glyphRange); i++ )
{
charIndex = [refLayoutManager characterIndexForGlyphAtIndex:i];
charDict = [refTextStorage attributesAtIndex:charIndex
effectiveRange:nil];
charFont = [charDict objectForKey:NSFontAttributeName];
lfRect = [refLayoutManager lineFragmentRectForGlyphAtIndex:i
effectiveRange:nil];
glyph = [refLayoutManager glyphAtIndex:i isValidIndex:&isValid];
if( isValid )
{
glyphLoc = [refLayoutManager locationForGlyphAtIndex:i];
glyphRect = [charFont boundingRectForGlyph:glyph];
if(i== glyphRange.location)
firstGlyphLoc = glyphLoc;
glyphLoc.x -= firstGlyphLoc.x;
glyphLoc.y -= firstGlyphLoc.y;
glyphRect = NSOffsetRect(glyphRect,glyphLoc.x,glyphLoc.y);
}
So, since this causes glyph regeneration, is there anyway to prevent
glyph regeneration when it's not needed so I can use the usual
notification? I've tried shutting off background glyph regeneration, but
it only caused more work to be needed. Or, is there another notification
that could be caught?
Thanks,
Brock Brandenberg
----- industrial design @ bergdesign.com ------
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.