I'm working on implementing text flow into an irregular shape using a custom subclass of NSTextContainer. I think my problem stems from the lack of detail in the documentation, since I've implemented it based on what is there but it doesn't work correctly.

It's OK for a convex shape where there is no splitting of lines, but if there's any reason to split a line, it goes a bit wrong, as seen here:

http://apptree.net/images/textflow1.jpg

I've verified that my algorithm for finding the intersections of the fragment rectangle and the shape edges is correct, you can see that working from this image:

http://apptree.net/images/textflow2.jpg

So what remains is the logic in my text container for returning the split-up lines. Also, at this stage I'm not trying anything fancy with the font - it's all the same font, same line height. (I've seen a posting about having problem splitting a line when the font height varies across the split, but that's not the case here).

According to the docs:

"In the second example [split line], the proposed rectangle crosses a hole, so the text container must return a shorter rectangle (the white rectangle on the left) along with a remainder (the white rectangle on the right). The next rectangle proposed by the typesetter will then be this remainder rectangle which will be returned unchanged by the text container."

What this suggests to me is that the text container needs to keep track of the previous non-zero remainder rect that it set, and if the proposedRect is the same, then it should return it unchanged, resetting the remainderRect. Here's the code to do just that:

- (NSRect)                      lineFragmentRectForProposedRect:(NSRect) 
proposedRect
                                        sweepDirection:(NSLineSweepDirection) 
sweepDirection
                                        
movementDirection:(NSLineMovementDirection) movementDirection
                                        remainingRect:(NSRectPointer) 
remainingRect
{
        #pragma unused(sweepDirection)
        #pragma unused(movementDirection)

        if( NSEqualRects( proposedRect, mLastRemainderRect ))
        {
// proposed rect matches last remainder rect issued, so return it unchanged as per docs
                mLastRemainderRect = NSZeroRect;
                
                if( remainingRect != nil )
                        *remainingRect = NSZeroRect;
                return proposedRect;
        }

        NSRect remRect = NSZeroRect;
NSRect result = [mPath lineFragmentRectForProposedRect:proposedRect remainingRect:&remRect];
        
        if( remainingRect != nil )
        {
                *remainingRect = remRect;
                mLastRemainderRect = remRect;   //track the remainder rect for 
next call
        }
        
        return result;
}

Here the hard work of modifying the line fragment rects is really done by the NSBezierPath category method lineFragmentRectForProposedRect:remainingRect: but that's been tested separately and definitely returns the right rects (as seen in image 2 above). So the fault I'm pretty sure lies in the (possibly naive) logic here and/or the differences between what the docs say and what NSLayoutManager really does. Either that or I've done something silly in my interpretation of the docs and/or the code logic above - but I can't see what it is. If anyone's familiar with solving this problem, I'd love to hear any insight you might have!

tia,


Graham




_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to