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 ([email protected])
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 [email protected]