mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 00:50:38 +00:00
Attributed string additions implemented.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4815 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
95d6f663cf
commit
4b2f418176
2 changed files with 312 additions and 22 deletions
|
@ -1,3 +1,8 @@
|
|||
Fri Sep 3 22:45:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSAttributedString.m: implemented (untested) most of the
|
||||
missing methods, and fixed a few memory leaks.
|
||||
|
||||
Thu Sep 2 16:42:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* NSWorkspace.m: Trivial fix to pass app when opening files.
|
||||
|
|
|
@ -1,4 +1,75 @@
|
|||
#include <AppKit/NSAttributedString.h>
|
||||
#include <AppKit/NSParagraphStyle.h>
|
||||
#include <AppKit/NSTextAttachment.h>
|
||||
|
||||
/*
|
||||
* function to return a character set containing characters that
|
||||
* separate words.
|
||||
*/
|
||||
static NSCharacterSet*
|
||||
wordBreakCSet()
|
||||
{
|
||||
static NSCharacterSet *cset = nil;
|
||||
|
||||
if (cset == nil)
|
||||
{
|
||||
NSMutableCharacterSet *m = [NSMutableCharacterSet new];
|
||||
|
||||
cset = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [NSCharacterSet punctuationCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [NSCharacterSet controlCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [NSCharacterSet illegalCharacterSet];
|
||||
[m formUnionWithCharacterSet: cset];
|
||||
cset = [m copy];
|
||||
RELEASE(m);
|
||||
}
|
||||
return cset;
|
||||
}
|
||||
|
||||
/*
|
||||
* function to return a character set containing characters that
|
||||
* are legal within words.
|
||||
*/
|
||||
static NSCharacterSet*
|
||||
wordCSet()
|
||||
{
|
||||
static NSCharacterSet *cset = nil;
|
||||
|
||||
if (cset == nil)
|
||||
{
|
||||
cset = [[wordBreakCSet() invertedSet] copy];
|
||||
}
|
||||
return cset;
|
||||
}
|
||||
|
||||
/*
|
||||
* function to return a character set containing paragraph separators
|
||||
*/
|
||||
static NSCharacterSet*
|
||||
paraBreakCSet()
|
||||
{
|
||||
static NSCharacterSet *cset = nil;
|
||||
|
||||
if (cset == nil)
|
||||
{
|
||||
NSMutableCharacterSet *m = [NSMutableCharacterSet new];
|
||||
|
||||
/*
|
||||
* Build set with characters specified in MacOS-X documentation for
|
||||
* [NSAttributedString -fixParagraphStyleAttributeInRange:]
|
||||
*/
|
||||
[m addCharactersInRange: NSMakeRange(0x000A, 1)]; /* CR */
|
||||
[m addCharactersInRange: NSMakeRange(0x000D, 1)]; /* LF */
|
||||
[m addCharactersInRange: NSMakeRange(0x2028, 1)]; /* line sep */
|
||||
[m addCharactersInRange: NSMakeRange(0x2029, 1)]; /* para sep */
|
||||
cset = [m copy];
|
||||
RELEASE(m);
|
||||
}
|
||||
return cset;
|
||||
}
|
||||
|
||||
@implementation NSAttributedString (AppKit)
|
||||
|
||||
|
@ -116,11 +187,85 @@
|
|||
|
||||
- (NSRange) doubleClickAtIndex: (unsigned)location
|
||||
{
|
||||
NSString *str = [self string];
|
||||
unsigned length = [str length];
|
||||
NSRange scanRange;
|
||||
NSRange startRange;
|
||||
NSRange endRange;
|
||||
|
||||
scanRange = NSMakeRange(0, location);
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
options: NSBackwardsSearch|NSLiteralSearch
|
||||
range: scanRange];
|
||||
scanRange = NSMakeRange(location, length - location);
|
||||
endRange = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
options: NSLiteralSearch
|
||||
range: scanRange];
|
||||
if (startRange.length == 0)
|
||||
{
|
||||
location = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
location = startRange.location + startRange.length;
|
||||
}
|
||||
if (endRange.length == 0)
|
||||
{
|
||||
length = length - location;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = endRange.location - location;
|
||||
}
|
||||
return NSMakeRange(location, length);
|
||||
}
|
||||
|
||||
- (unsigned) nextWordFromIndex: (unsigned)location
|
||||
forward: (BOOL)isForward
|
||||
{
|
||||
if (isForward)
|
||||
{
|
||||
NSString *str = [self string];
|
||||
unsigned length = [str length];
|
||||
NSRange range;
|
||||
|
||||
range = NSMakeRange(location, length - location);
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
return NSNotFound;
|
||||
location = range.location;
|
||||
range = NSMakeRange(location, length - location);
|
||||
range = [str rangeOfCharacterFromSet: wordCSet()
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
return NSNotFound;
|
||||
return range.location;
|
||||
}
|
||||
else if (location > 0)
|
||||
{
|
||||
NSString *str = [self string];
|
||||
NSRange range;
|
||||
|
||||
range = NSMakeRange(0, location);
|
||||
range = [str rangeOfCharacterFromSet: wordBreakCSet()
|
||||
options: NSBackwardsSearch|NSLiteralSearch
|
||||
range: range];
|
||||
location = range.location;
|
||||
range = NSMakeRange(0, location);
|
||||
range = [str rangeOfCharacterFromSet: wordCSet()
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
return NSNotFound;
|
||||
return range.location;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NSNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -206,7 +351,7 @@ documentAttributes: (NSDictionary**)dict
|
|||
sValue++;
|
||||
|
||||
[self addAttribute: NSSuperscriptAttributeName
|
||||
value: [[NSNumber alloc] initWithInt: sValue]
|
||||
value: [NSNumber numberWithInt: sValue]
|
||||
range: range];
|
||||
}
|
||||
|
||||
|
@ -224,59 +369,199 @@ documentAttributes: (NSDictionary**)dict
|
|||
sValue--;
|
||||
|
||||
[self addAttribute: NSSuperscriptAttributeName
|
||||
value: [[NSNumber alloc] initWithInt: sValue]
|
||||
value: [NSNumber numberWithInt: sValue]
|
||||
range: range];
|
||||
}
|
||||
|
||||
- (void)unscriptRange:(NSRange)range
|
||||
- (void) unscriptRange: (NSRange)range
|
||||
{
|
||||
[self addAttribute:NSSuperscriptAttributeName value:[[NSNumber alloc]
|
||||
initWithInt:0] range:range];
|
||||
[self addAttribute: NSSuperscriptAttributeName
|
||||
value: [NSNumber numberWithInt: 0]
|
||||
range: range];
|
||||
}
|
||||
|
||||
- (void)applyFontTraits:(NSFontTraitMask)traitMask range:(NSRange)range
|
||||
- (void) applyFontTraits: (NSFontTraitMask)traitMask range: (NSRange)range
|
||||
{
|
||||
/* We don't use font traits yet, oops. */
|
||||
/*
|
||||
id value;
|
||||
|
||||
value = [self attribute:NSFontAttributeName
|
||||
atIndex:range.location effectiveRange:range];
|
||||
value = [self attribute: NSFontAttributeName
|
||||
atIndex: range.location
|
||||
effectiveRange: range];
|
||||
|
||||
[value setFontTraits:traitMask];
|
||||
[value setFontTraits: traitMask];
|
||||
|
||||
[self addAttribute:NSFontAttributeName value:value range:range];
|
||||
[self addAttribute: NSFontAttributeName value: value range: range];
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)setAlignment:(NSTextAlignment)alignment range:(NSRange)range
|
||||
- (void) setAlignment: (NSTextAlignment)alignment range: (NSRange)range
|
||||
{
|
||||
id value;
|
||||
|
||||
value = [self attribute:NSParagraphStyleAttributeName
|
||||
atIndex:range.location effectiveRange:&range];
|
||||
value = [self attribute: NSParagraphStyleAttributeName
|
||||
atIndex: range.location
|
||||
effectiveRange: &range];
|
||||
|
||||
[value setAlignment:alignment];
|
||||
[value setAlignment: alignment];
|
||||
|
||||
[self addAttribute:NSParagraphStyleAttributeName value:value range:range];
|
||||
[self addAttribute: NSParagraphStyleAttributeName value: value range: range];
|
||||
}
|
||||
|
||||
- (void)fixAttributesInRange:(NSRange)range
|
||||
- (void) fixAttributesInRange: (NSRange)range
|
||||
{
|
||||
[self fixFontAttributeInRange:range];
|
||||
[self fixParagraphStyleAttributeInRange:range];
|
||||
[self fixAttachmentAttributeInRange:range];
|
||||
[self fixFontAttributeInRange: range];
|
||||
[self fixParagraphStyleAttributeInRange: range];
|
||||
[self fixAttachmentAttributeInRange: range];
|
||||
}
|
||||
|
||||
- (void)fixFontAttributeInRange:(NSRange)range
|
||||
- (void) fixFontAttributeInRange: (NSRange)range
|
||||
{
|
||||
}
|
||||
|
||||
- (void)fixParagraphStyleAttributeInRange:(NSRange)range
|
||||
- (void) fixParagraphStyleAttributeInRange: (NSRange)range
|
||||
{
|
||||
NSString *str = [self string];
|
||||
unsigned length = [str length];
|
||||
unsigned location;
|
||||
NSRange r;
|
||||
|
||||
if (range.location > 0)
|
||||
{
|
||||
/*
|
||||
* Extend range backward to take in entire paragraph if necessary.
|
||||
*/
|
||||
r = NSMakeRange(0, range.location);
|
||||
r = [str rangeOfCharacterFromSet: paraBreakCSet()
|
||||
options: NSBackwardsSearch|NSLiteralSearch
|
||||
range: r];
|
||||
if (r.length == 0)
|
||||
{
|
||||
/*
|
||||
* No paragraph before this in range - so extend range right
|
||||
* back to the start of the string.
|
||||
*/
|
||||
range.length += range.location;
|
||||
range.location = 0;
|
||||
}
|
||||
else if (r.location + 1 < range.location)
|
||||
{
|
||||
range.length += (range.location - r.location - 1);
|
||||
range.location = r.location + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Extend range forwards to take in entire paragraph if necessary.
|
||||
*/
|
||||
location = r.location + r.length;
|
||||
if (location > 0)
|
||||
location--;
|
||||
r = NSMakeRange(location, length - location);
|
||||
r = [str rangeOfCharacterFromSet: paraBreakCSet()
|
||||
options: NSLiteralSearch
|
||||
range: r];
|
||||
if (r.length > 0 && r.location > location)
|
||||
range.length += (r.location - location);
|
||||
|
||||
/*
|
||||
* Now try to step through the range fixing up the paragraph styles in
|
||||
* each paragraph so the entire paragraph has the same style as the
|
||||
* first character in the paragraph.
|
||||
*/
|
||||
while (range.length > 0)
|
||||
{
|
||||
NSParagraphStyle *style;
|
||||
NSRange found;
|
||||
unsigned end;
|
||||
|
||||
/*
|
||||
* Determine position of next paragraph end.
|
||||
*/
|
||||
r = [str rangeOfCharacterFromSet: paraBreakCSet()
|
||||
options: NSLiteralSearch
|
||||
range: range];
|
||||
if (r.length == 0)
|
||||
end = NSMaxRange(range);
|
||||
else
|
||||
end = r.location + 1;
|
||||
|
||||
/*
|
||||
* get the style in effect at the paragraph start.
|
||||
*/
|
||||
style = [self attribute: NSParagraphStyleAttributeName
|
||||
atIndex: location
|
||||
effectiveRange: &found];
|
||||
/*
|
||||
* Fix up this paragraph to have the starting style.
|
||||
*/
|
||||
while (NSMaxRange(found) < end)
|
||||
{
|
||||
NSParagraphStyle *nextStyle;
|
||||
NSRange nextFound;
|
||||
|
||||
nextStyle = [self attribute: NSParagraphStyleAttributeName
|
||||
atIndex: NSMaxRange(found)
|
||||
effectiveRange: &nextFound];
|
||||
if (nextStyle == style || [nextStyle isEqual: style] == YES)
|
||||
{
|
||||
found = nextFound;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Styles differ - add the old style to the remainder of the
|
||||
* range.
|
||||
*/
|
||||
found.location = NSMaxRange(found);
|
||||
found.length = end - found.location;
|
||||
[self addAttribute: NSParagraphStyleAttributeName
|
||||
value: style
|
||||
range: found];
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Adjust the range to start at the beginning of the next paragraph.
|
||||
*/
|
||||
range.length = NSMaxRange(range) - end;
|
||||
range.location = end;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fixAttachmentAttributeInRange:(NSRange)range
|
||||
- (void) fixAttachmentAttributeInRange: (NSRange)range
|
||||
{
|
||||
unsigned location = range.location;
|
||||
unsigned end = NSMaxRange(range);
|
||||
|
||||
while (location < end)
|
||||
{
|
||||
NSDictionary *attr;
|
||||
|
||||
attr = [self attributesAtIndex: location effectiveRange: &range];
|
||||
if ([attr objectForKey: NSAttachmentAttributeName] != nil)
|
||||
{
|
||||
unichar buf[range.length];
|
||||
unsigned pos = 0;
|
||||
|
||||
[[self string] getCharacters: buf range: range];
|
||||
while (pos < range.length)
|
||||
{
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
|
||||
while (pos < range.length && buf[pos] == NSAttachmentCharacter)
|
||||
pos++;
|
||||
start = pos;
|
||||
while (pos < range.length && buf[pos] == NSAttachmentCharacter)
|
||||
pos++;
|
||||
end = pos;
|
||||
if (start != end)
|
||||
[self removeAttribute: NSAttachmentAttributeName
|
||||
range: NSMakeRange(start, end - start)];
|
||||
}
|
||||
}
|
||||
location = NSMaxRange(range);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue