mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 14:00:37 +00:00
Optimizations
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8321 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
6284321acb
commit
352ef9339a
1 changed files with 271 additions and 231 deletions
|
@ -41,19 +41,31 @@
|
|||
#include "Parsers/rtfConsumer.h"
|
||||
#include "Parsers/RTFProducer.h"
|
||||
|
||||
/*
|
||||
* function to return a character set containing characters that
|
||||
* separate words.
|
||||
*/
|
||||
static NSCharacterSet*
|
||||
wordBreakCSet()
|
||||
{
|
||||
static NSCharacterSet *cset = nil;
|
||||
/* Cache class pointers to avoid the expensive lookup by string. */
|
||||
static Class dictionaryClass = nil;
|
||||
static Class stringClass = nil;
|
||||
|
||||
if (cset == nil)
|
||||
{
|
||||
NSMutableCharacterSet *m = [NSMutableCharacterSet new];
|
||||
/* A character set containing characters that separate words. */
|
||||
static NSCharacterSet *wordBreakCSet = nil;
|
||||
/* A character set containing characters that are legal within words. */
|
||||
static NSCharacterSet *wordCSet = nil;
|
||||
/* A String containing the attachment character */
|
||||
static NSString *attachmentString = nil;
|
||||
|
||||
|
||||
/* This function initializes all the previous cached values. */
|
||||
static void cache_init_real ()
|
||||
{
|
||||
NSMutableCharacterSet *m;
|
||||
NSCharacterSet *cset;
|
||||
unichar ch = NSAttachmentCharacter;
|
||||
|
||||
/* Initializes Class pointer cache */
|
||||
dictionaryClass = [NSDictionary class];
|
||||
stringClass = [NSString class];
|
||||
|
||||
/* Initializes wordBreakCSet */
|
||||
m = [NSMutableCharacterSet new];
|
||||
cset = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [NSCharacterSet punctuationCharacterSet];
|
||||
|
@ -62,60 +74,63 @@ wordBreakCSet()
|
|||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [NSCharacterSet illegalCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [m copy];
|
||||
wordBreakCSet = [m copy];
|
||||
RELEASE (m);
|
||||
}
|
||||
return cset;
|
||||
|
||||
/* Initializes wordCSet */
|
||||
wordCSet = [[wordBreakCSet invertedSet] copy];
|
||||
|
||||
/* Initializes attachmentString */
|
||||
attachmentString = [stringClass stringWithCharacters: &ch length: 1];
|
||||
RETAIN (attachmentString);
|
||||
}
|
||||
|
||||
/*
|
||||
* function to return a character set containing characters that
|
||||
* are legal within words.
|
||||
*/
|
||||
static NSCharacterSet*
|
||||
wordCSet()
|
||||
/* This inline function calls cache_init_real () the first time it is
|
||||
invoked, and does nothing afterwards. Thus we get both speed
|
||||
(cache_init is inlined and only compares a pointer to nil when the
|
||||
cache has been initialized) and limit memory consumption (we are
|
||||
not copying everywhere the real initialization code, which is in
|
||||
cache_real_init (), which is not inlined.).*/
|
||||
static inline void cache_init ()
|
||||
{
|
||||
static NSCharacterSet *cset = nil;
|
||||
|
||||
if (cset == nil)
|
||||
if (dictionaryClass == nil)
|
||||
{
|
||||
cset = [[wordBreakCSet() invertedSet] copy];
|
||||
cache_init_real ();
|
||||
}
|
||||
return cset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a String containing the attachment character
|
||||
*/
|
||||
static NSString *attachmentString()
|
||||
{
|
||||
static NSString *attach = nil;
|
||||
|
||||
if (attach == nil)
|
||||
{
|
||||
unichar ch = NSAttachmentCharacter;
|
||||
attach = RETAIN([NSString stringWithCharacters: &ch length: 1]);
|
||||
}
|
||||
return attach;
|
||||
}
|
||||
|
||||
|
||||
@implementation NSAttributedString (AppKit)
|
||||
|
||||
+ (NSAttributedString *)attributedStringWithAttachment:(NSTextAttachment *)attachment
|
||||
+ (NSAttributedString *) attributedStringWithAttachment:
|
||||
(NSTextAttachment *)attachment
|
||||
{
|
||||
NSDictionary *attributes = [NSDictionary dictionaryWithObject: attachment
|
||||
NSDictionary *attributes;
|
||||
|
||||
cache_init ();
|
||||
|
||||
attributes = [dictionaryClass dictionaryWithObject: attachment
|
||||
forKey: NSAttachmentAttributeName];
|
||||
|
||||
return AUTORELEASE([[self alloc] initWithString: attachmentString()
|
||||
return AUTORELEASE ([[self alloc] initWithString: attachmentString
|
||||
attributes: attributes]);
|
||||
}
|
||||
|
||||
- (BOOL) containsAttachments
|
||||
{
|
||||
NSRange aRange = [[self string] rangeOfString: attachmentString()];
|
||||
NSRange aRange;
|
||||
|
||||
return aRange.length;
|
||||
cache_init ();
|
||||
|
||||
aRange = [[self string] rangeOfString: attachmentString];
|
||||
|
||||
if (aRange.length > 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *) fontAttributesInRange: (NSRange)range
|
||||
|
@ -136,50 +151,30 @@ static NSString *attachmentString()
|
|||
effectiveRange: &range];
|
||||
|
||||
if (sel == 0)
|
||||
{
|
||||
sel = @selector (objectForKey:);
|
||||
}
|
||||
objForKey = [all methodForSelector: sel];
|
||||
|
||||
keys[count] = NSFontAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
#define NSATT_GET_ATTRIBUTE(attribute) \
|
||||
keys[count] = attribute; \
|
||||
objects[count] = (*objForKey) (all, sel, keys[count]); \
|
||||
if (objects[count] != nil) count++;
|
||||
|
||||
keys[count] = NSForegroundColorAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
NSATT_GET_ATTRIBUTE (NSFontAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSForegroundColorAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSBackgroundColorAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSUnderlineStyleAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSSuperscriptAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSBaselineOffsetAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSKernAttributeName);
|
||||
NSATT_GET_ATTRIBUTE (NSLigatureAttributeName);
|
||||
|
||||
keys[count] = NSBackgroundColorAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
#undef NSATT_GET_ATTRIBUTE
|
||||
|
||||
keys[count] = NSUnderlineStyleAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
cache_init ();
|
||||
|
||||
keys[count] = NSSuperscriptAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
|
||||
keys[count] = NSBaselineOffsetAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
|
||||
keys[count] = NSKernAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
|
||||
keys[count] = NSLigatureAttributeName;
|
||||
objects[count] = (*objForKey)(all, sel, keys[count]);
|
||||
if (objects[count] != nil)
|
||||
count++;
|
||||
|
||||
return [NSDictionary dictionaryWithObjects: objects
|
||||
return [dictionaryClass dictionaryWithObjects: objects
|
||||
forKeys: keys
|
||||
count: count];
|
||||
}
|
||||
|
@ -188,6 +183,8 @@ static NSString *attachmentString()
|
|||
{
|
||||
id style;
|
||||
|
||||
cache_init ();
|
||||
|
||||
if (NSMaxRange (range) > [self length])
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
@ -200,10 +197,11 @@ static NSString *attachmentString()
|
|||
|
||||
if (style != nil)
|
||||
{
|
||||
return [NSDictionary dictionaryWithObject: style
|
||||
return [dictionaryClass dictionaryWithObject: style
|
||||
forKey: NSParagraphStyleAttributeName];
|
||||
}
|
||||
return [NSDictionary dictionary];
|
||||
|
||||
return [dictionaryClass dictionary];
|
||||
}
|
||||
|
||||
- (unsigned) lineBreakBeforeIndex: (unsigned)location
|
||||
|
@ -214,6 +212,8 @@ static NSString *attachmentString()
|
|||
NSRange scanRange;
|
||||
NSRange startRange;
|
||||
|
||||
cache_init ();
|
||||
|
||||
if (NSMaxRange (aRange) > length || location > length)
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
@ -221,10 +221,12 @@ static NSString *attachmentString()
|
|||
}
|
||||
|
||||
if (!NSLocationInRange (location, aRange))
|
||||
{
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
scanRange = NSMakeRange (aRange.location, location - aRange.location);
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
options: NSBackwardsSearch | NSLiteralSearch
|
||||
range: scanRange];
|
||||
if (startRange.length == 0)
|
||||
|
@ -245,6 +247,8 @@ static NSString *attachmentString()
|
|||
NSRange startRange;
|
||||
NSRange endRange;
|
||||
|
||||
cache_init ();
|
||||
|
||||
if (location > length)
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
@ -252,11 +256,11 @@ static NSString *attachmentString()
|
|||
}
|
||||
|
||||
scanRange = NSMakeRange (0, location);
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
options: NSBackwardsSearch|NSLiteralSearch
|
||||
range: scanRange];
|
||||
scanRange = NSMakeRange (location, length - location);
|
||||
endRange = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
endRange = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
options: NSLiteralSearch
|
||||
range: scanRange];
|
||||
if (startRange.length == 0)
|
||||
|
@ -265,8 +269,9 @@ static NSString *attachmentString()
|
|||
}
|
||||
else
|
||||
{
|
||||
location = startRange.location + startRange.length;
|
||||
location = NSMaxRange (startRange);
|
||||
}
|
||||
|
||||
if (endRange.length == 0)
|
||||
{
|
||||
length = length - location;
|
||||
|
@ -291,41 +296,58 @@ static NSString *attachmentString()
|
|||
format: @"RangeError in method -nextWordFromIndex:forward:"];
|
||||
}
|
||||
|
||||
cache_init ();
|
||||
|
||||
if (isForward)
|
||||
{
|
||||
range = NSMakeRange (location, length - location);
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
range = NSMakeRange (range.location, length - range.location);
|
||||
range = [str rangeOfCharacterFromSet: wordCSet()
|
||||
range = [str rangeOfCharacterFromSet: wordCSet
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
return range.location;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL inWord = [wordCSet() characterIsMember: [str characterAtIndex: location]];
|
||||
BOOL inWord;
|
||||
|
||||
inWord = [wordCSet characterIsMember: [str characterAtIndex: location]];
|
||||
|
||||
range = NSMakeRange (0, location);
|
||||
|
||||
if (!inWord)
|
||||
{
|
||||
range = [str rangeOfCharacterFromSet: wordCSet()
|
||||
range = [str rangeOfCharacterFromSet: wordCSet
|
||||
options: NSBackwardsSearch | NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
range = NSMakeRange (0, range.location);
|
||||
}
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
options: NSBackwardsSearch | NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NSMaxRange (range);
|
||||
}
|
||||
}
|
||||
|
@ -334,9 +356,12 @@ static NSString *attachmentString()
|
|||
documentAttributes: (NSDictionary **)dict
|
||||
{
|
||||
// FIXME: This expects the file to be RTFD
|
||||
return [self initWithRTFDFileWrapper: [[NSFileWrapper alloc]
|
||||
initWithPath: path]
|
||||
documentAttributes: dict];
|
||||
NSFileWrapper *fw;
|
||||
|
||||
fw = [[NSFileWrapper alloc] initWithPath: path];
|
||||
AUTORELEASE (fw);
|
||||
|
||||
return [self initWithRTFDFileWrapper: fw documentAttributes: dict];
|
||||
}
|
||||
|
||||
- (id) initWithURL: (NSURL *)url
|
||||
|
@ -435,15 +460,20 @@ documentAttributes: (NSDictionary**)dict
|
|||
format: @"RangeError in method -superscriptRange:"];
|
||||
}
|
||||
|
||||
// We take the value form the first character and use it for the whole range
|
||||
// We take the value from the first character and use it for the whole range
|
||||
value = [self attribute: NSSuperscriptAttributeName
|
||||
atIndex: range.location
|
||||
effectiveRange: &effRange];
|
||||
|
||||
if (value != nil)
|
||||
{
|
||||
sValue = [value intValue] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sValue = 1;
|
||||
}
|
||||
|
||||
|
||||
[self addAttribute: NSSuperscriptAttributeName
|
||||
value: [NSNumber numberWithInt: sValue]
|
||||
|
@ -468,9 +498,13 @@ documentAttributes: (NSDictionary**)dict
|
|||
effectiveRange: &effRange];
|
||||
|
||||
if (value != nil)
|
||||
{
|
||||
sValue = [value intValue] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sValue = -1;
|
||||
}
|
||||
|
||||
[self addAttribute: NSSuperscriptAttributeName
|
||||
value: [NSNumber numberWithInt: sValue]
|
||||
|
@ -518,10 +552,12 @@ documentAttributes: (NSDictionary**)dict
|
|||
size: [font pointSize]];
|
||||
|
||||
if (font != nil)
|
||||
{
|
||||
[self addAttribute: NSFontAttributeName
|
||||
value: font
|
||||
range: NSIntersectionRange (effRange, range)];
|
||||
}
|
||||
}
|
||||
loc = NSMaxRange(effRange);
|
||||
}
|
||||
}
|
||||
|
@ -639,6 +675,8 @@ documentAttributes: (NSDictionary**)dict
|
|||
unsigned location = aRange.location;
|
||||
unsigned end = NSMaxRange (aRange);
|
||||
|
||||
cache_init ();
|
||||
|
||||
if (end > [self length])
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
@ -677,7 +715,7 @@ documentAttributes: (NSDictionary**)dict
|
|||
location = aRange.location;
|
||||
while (location < end)
|
||||
{
|
||||
NSRange range = [string rangeOfString: attachmentString()
|
||||
NSRange range = [string rangeOfString: attachmentString
|
||||
options: NSLiteralSearch
|
||||
range: NSMakeRange (location, end - location)];
|
||||
NSTextAttachment *attachment;
|
||||
|
@ -705,9 +743,11 @@ documentAttributes: (NSDictionary**)dict
|
|||
unsigned location = 0;
|
||||
unsigned end = [string length];
|
||||
|
||||
cache_init ();
|
||||
|
||||
while (location < end)
|
||||
{
|
||||
NSRange range = [string rangeOfString: attachmentString()
|
||||
NSRange range = [string rangeOfString: attachmentString
|
||||
options: NSLiteralSearch
|
||||
range: NSMakeRange (location, end - location)];
|
||||
NSTextAttachment *attachment;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue