From 64a5e9799129ccd3e8fcf2da84c980974bed74ab Mon Sep 17 00:00:00 2001 From: Christian Tietze Date: Thu, 3 Aug 2017 09:41:24 +0200 Subject: [PATCH] use NSTextStorage for speedups Replace NSMutableAttributesString with a concrete instance of NSTextStorage that performs optimizations when processing attribute changes. --- src/MacVim/MMTextStorage.h | 2 +- src/MacVim/MMTextStorage.m | 78 +++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/MacVim/MMTextStorage.h b/src/MacVim/MMTextStorage.h index e1ad0af5f1..3013c9a97f 100644 --- a/src/MacVim/MMTextStorage.h +++ b/src/MacVim/MMTextStorage.h @@ -25,7 +25,7 @@ typedef struct { @interface MMTextStorage : NSTextStorage { - NSMutableAttributedString *attribString; + NSTextStorage *backingStore; int maxRows, maxColumns; int actualRows, actualColumns; NSAttributedString *emptyRowString; diff --git a/src/MacVim/MMTextStorage.m b/src/MacVim/MMTextStorage.m index f3ce5e9a34..c7133e826b 100644 --- a/src/MacVim/MMTextStorage.m +++ b/src/MacVim/MMTextStorage.m @@ -72,7 +72,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; - (id)init { if ((self = [super init])) { - attribString = [[NSMutableAttributedString alloc] initWithString:@""]; + backingStore = [[NSTextStorage alloc] init]; // NOTE! It does not matter which font is set here, Vim will set its // own font on startup anyway. Just set some bogus values. font = [[NSFont userFixedPitchFontOfSize:0] retain]; @@ -104,19 +104,19 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; [font release]; font = nil; [defaultBackgroundColor release]; defaultBackgroundColor = nil; [defaultForegroundColor release]; defaultForegroundColor = nil; - [attribString release]; attribString = nil; + [backingStore release]; backingStore = nil; [super dealloc]; } - (NSString *)string { - return [attribString string]; + return [backingStore string]; } - (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)range { - return [attribString attributesAtIndex:index effectiveRange:range]; + return [backingStore attributesAtIndex:index effectiveRange:range]; } - (void)replaceCharactersInRange:(NSRange)range @@ -126,7 +126,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; ASLogWarn(@"Calling %@ on MMTextStorage is unsupported", NSStringFromSelector(_cmd)); #endif - //[attribString replaceCharactersInRange:range withString:string]; + //[backingStore replaceCharactersInRange:range withString:string]; } - (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range @@ -134,7 +134,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; // NOTE! This method must be implemented since the text system calls it // constantly to 'fix attributes', apply font substitution, etc. #if 0 - [attribString setAttributes:attributes range:range]; + [backingStore setAttributes:attributes range:range]; #elif 1 // HACK! If the font attribute is being modified, then ensure that the new // font has a fixed advancement which is either the same as the current @@ -153,7 +153,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; float adv = cellSize.width; - if ([attribString attribute:MMWideCharacterAttributeName + if ([backingStore attribute:MMWideCharacterAttributeName atIndex:range.location effectiveRange:NULL]) adv += adv; @@ -170,9 +170,9 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; dictionaryWithDictionary:attributes]; [newAttr setObject:newFont forKey:NSFontAttributeName]; - [attribString setAttributes:newAttr range:range]; + [backingStore setAttributes:newAttr range:range]; } else { - [attribString setAttributes:attributes range:range]; + [backingStore setAttributes:attributes range:range]; } #endif } @@ -329,15 +329,15 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; } // Mark these characters as wide. This attribute is subsequently checked - // when translating (row,col) pairs to offsets within 'attribString'. + // when translating (row,col) pairs to offsets within 'backingStore'. if (flags & DRAW_WIDE) [attributes setObject:[NSNull null] forKey:MMWideCharacterAttributeName]; // Replace characters in text storage and apply new attributes. NSRange r = NSMakeRange(range.location, [string length]); - [attribString replaceCharactersInRange:range withString:string]; - [attribString setAttributes:attributes range:r]; + [backingStore replaceCharactersInRange:range withString:string]; + [backingStore setAttributes:attributes range:r]; NSInteger changeInLength = [string length] - range.length; if (acells != cells || acol != col) { @@ -345,18 +345,18 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; // NOTE: A normal width character replaced a double width // character. To maintain the invariant that each row covers the // same amount of cells, we compensate by adding an empty column. - [attribString replaceCharactersInRange:NSMakeRange(NSMaxRange(r),0) + [backingStore replaceCharactersInRange:NSMakeRange(NSMaxRange(r),0) withAttributedString:[emptyRowString attributedSubstringFromRange:NSMakeRange(0,1)]]; ++changeInLength; #if 0 } else if (acol == col - 1) { - [attribString replaceCharactersInRange:NSMakeRange(r.location,0) + [backingStore replaceCharactersInRange:NSMakeRange(r.location,0) withAttributedString:[emptyRowString attributedSubstringFromRange:NSMakeRange(0,1)]]; ++changeInLength; } else if (acol == col + 1) { - [attribString replaceCharactersInRange:NSMakeRange(r.location-1,1) + [backingStore replaceCharactersInRange:NSMakeRange(r.location-1,1) withAttributedString:[emptyRowString attributedSubstringFromRange:NSMakeRange(0,2)]]; ++changeInLength; @@ -435,10 +435,10 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; } - NSAttributedString *srcString = [attribString + NSAttributedString *srcString = [backingStore attributedSubstringFromRange:srcRange]; - [attribString replaceCharactersInRange:destRange + [backingStore replaceCharactersInRange:destRange withAttributedString:srcString]; [self edited:(NSTextStorageEditedCharacters | NSTextStorageEditedAttributes) range:destRange @@ -471,9 +471,9 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; } - [attribString replaceCharactersInRange:destRange + [backingStore replaceCharactersInRange:destRange withAttributedString:emptyString]; - [attribString setAttributes:attribs + [backingStore setAttributes:attribs range:NSMakeRange(destRange.location, width)]; [self edited:(NSTextStorageEditedAttributes @@ -531,9 +531,9 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; } - NSAttributedString *srcString = [attribString + NSAttributedString *srcString = [backingStore attributedSubstringFromRange:srcRange]; - [attribString replaceCharactersInRange:destRange + [backingStore replaceCharactersInRange:destRange withAttributedString:srcString]; [self edited:(NSTextStorageEditedCharacters | NSTextStorageEditedAttributes) range:destRange @@ -566,9 +566,9 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; } - [attribString replaceCharactersInRange:destRange + [backingStore replaceCharactersInRange:destRange withAttributedString:emptyString]; - [attribString setAttributes:attribs + [backingStore setAttributes:attribs range:NSMakeRange(destRange.location, width)]; [self edited:(NSTextStorageEditedAttributes @@ -613,9 +613,9 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return; } - [attribString replaceCharactersInRange:range + [backingStore replaceCharactersInRange:range withAttributedString:emptyString]; - [attribString setAttributes:attribs + [backingStore setAttributes:attribs range:NSMakeRange(range.location, cells)]; [self edited:(NSTextStorageEditedAttributes @@ -917,7 +917,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; int cells = 1; NSRange r = [self charRangeForRow:row column:&col cells:&cells]; if (NSNotFound != r.location - && [attribString attribute:MMWideCharacterAttributeName + && [backingStore attribute:MMWideCharacterAttributeName atIndex:r.location effectiveRange:nil]) rect.size.width += rect.size.width; @@ -958,7 +958,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; if (!force && actualRows == maxRows && actualColumns == maxColumns) return; - NSRange oldRange = NSMakeRange(0, [attribString length]); + NSRange oldRange = NSMakeRange(0, [backingStore length]); actualRows = maxRows; actualColumns = maxColumns; @@ -990,16 +990,16 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; emptyRowString = [[NSAttributedString alloc] initWithString:rowString attributes:dict]; - [attribString release]; - attribString = [[NSMutableAttributedString alloc] init]; + [backingStore release]; + backingStore = [[NSMutableAttributedString alloc] init]; for (i=0; i 0) { - invalidRange = [[attribString string] + invalidRange = [[backingStore string] rangeOfCharacterFromSet:invalidCharacterSet options:NSLiteralSearch range:range]; if (NSNotFound == invalidRange.location) break; - [attribString replaceCharactersInRange:invalidRange withString:@" "]; + [backingStore replaceCharactersInRange:invalidRange withString:@" "]; end = NSMaxRange(invalidRange); range.length -= end - range.location;