Hi, I have inherited some code which has a subclass of NSATSTypesetter in it, 
and in the -willSetLineFragmentRect:forGlyphRange:usedRect:baselineOffset: 
method it works out whether it needs to put a page break in, and directly sets 
the currentTextContainer, currentTextContainerIndex, and 
currentTextContainerSize instance variables.

This is completely undocumented and presumably a very bad way to handle the 
pagination, so I want to fix it.

The problem is that I am not clear whether the typesetter is the place to do 
the pagination or whether it should be in the layout manager, and if so exactly 
how to handle the processing. Any advice on how best to handle the pagination 
would be most welcome.

Here's what got handed to me (in a subclass of NSATSTypesetter):

- (void)willSetLineFragmentRect:(NSRect *)lineRect 
forGlyphRange:(NSRange)glyphRange usedRect:(NSRect *)usedRect 
baselineOffset:(CGFloat *)baselineOffset {
    NSRange characterRange = [self characterRangeForGlyphRange:glyphRange 
actualGlyphRange:NULL];
    NSString *string = [[[[self layoutManager] textStorage] string] 
substringWithRange:characterRange];
    NSSize size = [[self currentTextContainer] containerSize];
    // This is more like the forecast maximum y which is the line height plus 
the origin y.
    CGFloat forecastedHeight = ((*lineRect).size.height*2.0) + 
(*lineRect).origin.y;
    
    // If the last character of the line fragment is not a paragraph marker, 
and the text is on the last line, then put the text on the next page. This is 
so the
    // text is not split so that the character name is on one page and the 
dialog is on another etc
    if ([string characterAtIndex:characterRange.length-1] != 
NSParagraphSeparatorCharacter) {
        if (forecastedHeight > size.height) {
            NSFont *font = [[[self layoutManager] textStorage] 
attribute:NSFontAttributeName atIndex:[self paragraphCharacterRange].location 
effectiveRange:NULL];
            
            NSDictionary *attrs = [[[self layoutManager] textStorage] 
attributesAtIndex:[self paragraphCharacterRange].location effectiveRange:NULL];
            NSString *temp = [[[[self layoutManager] textStorage] string] 
substringWithRange:[self paragraphCharacterRange]];
            NSSize stringSize = [temp sizeWithAttributes:attrs];
            
            lineRect->origin.y = 0.0;
            lineRect->size.height = stringSize.height;
            usedRect->origin.y = 0.0;
            usedRect->size.height = stringSize.height;
            
            *baselineOffset = [[self layoutManager] 
defaultBaselineOffsetForFont:font];
            
            if (currentTextContainer == [[self textContainers] lastObject]) {
                currentTextContainerIndex = NSNotFound;
                currentTextContainer = nil;
                currentTextContainerSize = NSZeroSize;
            } else {
                unsigned indexOfOldTC = [[self textContainers] 
indexOfObjectIdenticalTo:currentTextContainer];
                currentTextContainerIndex = indexOfOldTC+1;
                currentTextContainer = [[self textContainers] 
objectAtIndex:currentTextContainerIndex];
                currentTextContainerSize = [currentTextContainer containerSize];
            }
        }
    }
    
    // If the line is a character name, then we will always put it down a line 
below whatever section was above it.
    NSString *section = [self.screenwriterLayoutManager.screenwriterView 
sectionFromRange:[self paragraphCharacterRange]];
    if (section == SWCharacterSectionIdentifier) {
        if (forecastedHeight > size.height) {
            if (lineRect->origin.y > 0.001) {
                NSFont *font = [[[self layoutManager] textStorage] 
attribute:NSFontAttributeName atIndex:[self paragraphCharacterRange].location 
effectiveRange:NULL];
                
                                NSDictionary *attrs = [[[self layoutManager] 
textStorage] attributesAtIndex:[self paragraphCharacterRange].location 
effectiveRange:NULL];
                                NSString *temp = [[[[self layoutManager] 
textStorage] string] substringWithRange:[self paragraphCharacterRange]];
                                NSSize stringSize = [temp 
sizeWithAttributes:attrs];
                
                lineRect->origin.y = 0.0;
                lineRect->size.height = stringSize.height;
                usedRect->origin.y = 0.0;
                usedRect->size.height = stringSize.height;
                
                *baselineOffset = [[self layoutManager] 
defaultBaselineOffsetForFont:font];
                
                if (currentTextContainer == [[self textContainers] lastObject]) 
{
                    currentTextContainerIndex = NSNotFound;
                    currentTextContainer = nil;
                    currentTextContainerSize = NSZeroSize;
                } else {
                    unsigned indexOfOldTC = [[self textContainers] 
indexOfObjectIdenticalTo:currentTextContainer];
                    currentTextContainerIndex = indexOfOldTC+1;
                    currentTextContainer = [[self textContainers] 
objectAtIndex:currentTextContainerIndex];
                    currentTextContainerSize = [currentTextContainer 
containerSize];
                }
            }
        }
    }
}



PS Sorry about the number of questions at once - just seem to have run into 
multiple issues at once tonight.


Regards

Gideon



_______________________________________________

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to