mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-24 02:32:38 +00:00
discussion with Steve Naroff (before he left Apple) it was decided that the isa pointer should be regarded as an implementation detail and not part of the language, so direct references to it are deprecated (on OS X). This gives the runtime a bit more freedom to do secret isa-swizzling tricks. I've had these changes sitting in my copy for ages - no idea why they weren't committed. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@33111 72102866-910b-0410-8b05-ffd578937521
814 lines
19 KiB
Objective-C
814 lines
19 KiB
Objective-C
/** <title>NSParagraphStyle</title>
|
||
|
||
<abstract>NSParagraphStyle and NSMutableParagraphStyle hold paragraph style
|
||
information NSTextTab holds information about a single tab stop</abstract>
|
||
|
||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||
|
||
Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||
Date March 1999
|
||
|
||
This file is part of the GNUstep GUI Library.
|
||
|
||
This library is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU Lesser General Public
|
||
License as published by the Free Software Foundation; either
|
||
version 2 of the License, or (at your option) any later version.
|
||
|
||
This library is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public
|
||
License along with this library; see the file COPYING.LIB.
|
||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||
Boston, MA 02110-1301, USA.
|
||
*/
|
||
|
||
#import <Foundation/NSDictionary.h>
|
||
#import <Foundation/NSException.h>
|
||
#import "AppKit/NSParagraphStyle.h"
|
||
|
||
@implementation NSTextTab
|
||
|
||
- (id) initWithType: (NSTextTabType)type location: (float)loc
|
||
{
|
||
if ((self = [super init]))
|
||
{
|
||
_tabStopType = type;
|
||
_location = loc;
|
||
switch (type)
|
||
{
|
||
default:
|
||
case NSLeftTabStopType:
|
||
_alignment = NSLeftTextAlignment;
|
||
break;
|
||
case NSRightTabStopType:
|
||
_alignment = NSRightTextAlignment;
|
||
break;
|
||
case NSCenterTabStopType:
|
||
_alignment = NSCenterTextAlignment;
|
||
break;
|
||
case NSDecimalTabStopType:
|
||
_alignment = NSRightTextAlignment;
|
||
break;
|
||
}
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (id) initWithTextAlignment: (NSTextAlignment)align
|
||
location: (float)loc
|
||
options: (NSDictionary *)options
|
||
{
|
||
NSTextTabType type;
|
||
|
||
switch (align)
|
||
{
|
||
default:
|
||
case NSLeftTextAlignment:
|
||
type = NSLeftTabStopType;
|
||
break;
|
||
case NSRightTextAlignment:
|
||
if ([options objectForKey: NSTabColumnTerminatorsAttributeName] != nil)
|
||
{
|
||
type = NSDecimalTabStopType;
|
||
}
|
||
else
|
||
{
|
||
type = NSRightTabStopType;
|
||
}
|
||
break;
|
||
case NSCenterTextAlignment:
|
||
type = NSCenterTabStopType;
|
||
break;
|
||
case NSJustifiedTextAlignment:
|
||
type = NSLeftTabStopType;
|
||
break;
|
||
case NSNaturalTextAlignment:
|
||
// FIXME: Get from language user setting
|
||
type = YES ? NSLeftTabStopType : NSRightTabStopType;
|
||
break;
|
||
}
|
||
|
||
if ((self = [self initWithType: type location: loc]))
|
||
{
|
||
_alignment = align;
|
||
ASSIGN(_options, options);
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void) dealloc
|
||
{
|
||
RELEASE(_options);
|
||
[super dealloc];
|
||
}
|
||
|
||
- (id) copyWithZone: (NSZone*)aZone
|
||
{
|
||
NSTextTab *copy;
|
||
|
||
if (NSShouldRetainWithZone(self, aZone) == YES)
|
||
return RETAIN(self);
|
||
|
||
copy = (NSTextTab *)NSCopyObject(self, 0, aZone);
|
||
copy->_options = [_options copyWithZone: aZone];
|
||
return copy;
|
||
}
|
||
|
||
- (NSComparisonResult) compare: (id)anObject
|
||
{
|
||
float loc;
|
||
|
||
if (anObject == self)
|
||
return NSOrderedSame;
|
||
if (anObject == nil || ([anObject isKindOfClass: object_getClass(self)] == NO))
|
||
return NSOrderedAscending;
|
||
loc = ((NSTextTab*)anObject)->_location;
|
||
if (_location < loc)
|
||
return NSOrderedAscending;
|
||
else if (_location > loc)
|
||
return NSOrderedDescending;
|
||
else
|
||
return NSOrderedSame;
|
||
}
|
||
|
||
- (NSUInteger) hash
|
||
{
|
||
unsigned val = (unsigned)_location;
|
||
|
||
val ^= (unsigned)_tabStopType;
|
||
return val;
|
||
}
|
||
|
||
- (BOOL) isEqual: (id)anObject
|
||
{
|
||
if (anObject == self)
|
||
return YES;
|
||
if ([anObject isKindOfClass: object_getClass(self)] == NO)
|
||
return NO;
|
||
else if (((NSTextTab*)anObject)->_tabStopType != _tabStopType)
|
||
return NO;
|
||
else if (((NSTextTab*)anObject)->_location != _location)
|
||
return NO;
|
||
return YES;
|
||
}
|
||
|
||
- (float) location
|
||
{
|
||
return _location;
|
||
}
|
||
|
||
- (NSTextTabType) tabStopType
|
||
{
|
||
return _tabStopType;
|
||
}
|
||
- (NSTextAlignment) alignment
|
||
{
|
||
return _alignment;
|
||
}
|
||
|
||
- (NSDictionary *) options
|
||
{
|
||
return _options;
|
||
}
|
||
|
||
- (id) initWithCoder: (NSCoder *)aCoder
|
||
{
|
||
if ([aCoder allowsKeyedCoding])
|
||
{
|
||
_location = [aCoder decodeFloatForKey: @"NSLocation"];
|
||
}
|
||
else
|
||
{
|
||
// FIXME
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void) encodeWithCoder: (NSCoder *)aCoder
|
||
{
|
||
if ([aCoder allowsKeyedCoding])
|
||
{
|
||
[aCoder encodeFloat: _location forKey: @"NSLocation"];
|
||
}
|
||
else
|
||
{
|
||
// FIXME
|
||
}
|
||
}
|
||
|
||
@end
|
||
|
||
|
||
|
||
@implementation NSParagraphStyle
|
||
|
||
static NSParagraphStyle *defaultStyle = nil;
|
||
|
||
+ (NSParagraphStyle*) defaultParagraphStyle
|
||
{
|
||
if (defaultStyle == nil)
|
||
{
|
||
NSParagraphStyle *style = [[self alloc] init];
|
||
int i;
|
||
|
||
for (i = 0; i < 12; i++)
|
||
{
|
||
NSTextTab *tab;
|
||
|
||
tab = [[NSTextTab alloc] initWithType: NSLeftTabStopType
|
||
location: (i + 1) * 28.0];
|
||
[style->_tabStops addObject: tab];
|
||
RELEASE(tab);
|
||
}
|
||
defaultStyle = style;
|
||
}
|
||
return defaultStyle;
|
||
}
|
||
|
||
+ (void) initialize
|
||
{
|
||
if (self == [NSParagraphStyle class])
|
||
{
|
||
/* Set the class version to 2, as the writing direction is now
|
||
stored in the encoding */
|
||
[self setVersion: 2];
|
||
}
|
||
}
|
||
|
||
+ (NSWritingDirection) defaultWritingDirectionForLanguage: (NSString*) language
|
||
{
|
||
static NSArray *rightToLeft;
|
||
NSWritingDirection writingDirection;
|
||
NSString *langCode = nil;
|
||
|
||
/* If language is 5/6 characters long with underscore in the middle,
|
||
treat it as ISO language-region format. */
|
||
if ([language length] == 5 && [language characterAtIndex: 2] == '_')
|
||
langCode = [language substringToIndex: 2];
|
||
else if ([language length] == 6 && [language characterAtIndex: 3] == '_')
|
||
langCode = [language substringToIndex: 3];
|
||
/* Else if it's just two or three chars long, treat as ISO 639 code. */
|
||
else if ([language length] == 2 || [language length] == 3)
|
||
langCode = language;
|
||
|
||
if (!rightToLeft)
|
||
// Holds languages whose current scripts are written right to left.
|
||
rightToLeft = [[NSArray alloc] initWithObjects: @"ar", @"ara", @"arc",
|
||
@"chi", @"fa", @"fas", @"he", @"heb", @"iw",
|
||
@"ji", @"kas", @"ks", @"ku", @"kur", @"pa",
|
||
@"pan", @"per" @"ps", @"pus", @"sd", @"snd",
|
||
@"syr", @"tk", @"tmh", @"tuk", @"ug",
|
||
@"uig", @"ur," @"urd", @"yi", @"yid", @"zh",
|
||
@"zho", nil];
|
||
if ([rightToLeft containsObject: langCode] == YES)
|
||
writingDirection = NSWritingDirectionRightToLeft;
|
||
else // If it's not RTL, assume LTR.
|
||
writingDirection = NSWritingDirectionLeftToRight;
|
||
|
||
return writingDirection;
|
||
}
|
||
|
||
- (void) dealloc
|
||
{
|
||
if (self == defaultStyle)
|
||
{
|
||
NSLog(@"Argh - attempt to dealloc the default paragraph style!");
|
||
return;
|
||
}
|
||
RELEASE(_tabStops);
|
||
RELEASE(_textBlocks);
|
||
RELEASE(_textLists);
|
||
[super dealloc];
|
||
}
|
||
|
||
- (id) init
|
||
{
|
||
if ((self = [super init]))
|
||
{
|
||
_alignment = NSNaturalTextAlignment;
|
||
//_firstLineHeadIndent = 0.0;
|
||
//_headIndent = 0.0;
|
||
_lineBreakMode = NSLineBreakByWordWrapping;
|
||
//_lineSpacing = 0.0;
|
||
//_maximumLineHeight = 0.0;
|
||
//_minimumLineHeight = 0.0;
|
||
//_paragraphSpacing = 0.0;
|
||
//_tailIndent = 0.0;
|
||
_baseDirection = NSWritingDirectionNaturalDirection;
|
||
_tabStops = [[NSMutableArray allocWithZone: [self zone]]
|
||
initWithCapacity: 12];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
/*
|
||
* "Leading": distance between the bottom of one line fragment and top
|
||
* of next (applied between lines in the same container).
|
||
* Can't be negative. This value is included in the line fragment
|
||
* heights in layout manager.
|
||
*/
|
||
- (float) lineSpacing
|
||
{
|
||
return _lineSpacing;
|
||
}
|
||
|
||
/*
|
||
* Distance between the bottom of this paragraph and top of next.
|
||
*/
|
||
- (float) paragraphSpacing
|
||
{
|
||
return _paragraphSpacing;
|
||
}
|
||
|
||
- (NSTextAlignment) alignment
|
||
{
|
||
return _alignment;
|
||
}
|
||
|
||
/*
|
||
* The following values are relative to the appropriate margin
|
||
* (depending on the paragraph direction)
|
||
*/
|
||
|
||
/*
|
||
* Distance from margin to front edge of paragraph
|
||
*/
|
||
- (float) headIndent
|
||
{
|
||
return _headIndent;
|
||
}
|
||
|
||
/*
|
||
* Distance from margin to back edge of paragraph; if negative or 0,
|
||
* from other margin
|
||
*/
|
||
- (float) tailIndent
|
||
{
|
||
return _tailIndent;
|
||
}
|
||
|
||
/*
|
||
* Distance from margin to edge appropriate for text direction
|
||
*/
|
||
- (float) firstLineHeadIndent
|
||
{
|
||
return _firstLineHeadIndent;
|
||
}
|
||
|
||
/*
|
||
* Distance from margin to tab stops
|
||
*/
|
||
- (NSArray *) tabStops
|
||
{
|
||
return AUTORELEASE ([_tabStops copyWithZone: NSDefaultMallocZone ()]);
|
||
}
|
||
|
||
/*
|
||
* Line height is the distance from bottom of descenders to to
|
||
* of ascenders; basically the line fragment height. Does not include
|
||
* lineSpacing (which is added after this computation).
|
||
*/
|
||
- (float) minimumLineHeight
|
||
{
|
||
return _minimumLineHeight;
|
||
}
|
||
|
||
/*
|
||
* 0 implies no maximum.
|
||
*/
|
||
- (float) maximumLineHeight
|
||
{
|
||
return _maximumLineHeight;
|
||
}
|
||
|
||
- (NSLineBreakMode) lineBreakMode
|
||
{
|
||
return _lineBreakMode;
|
||
}
|
||
|
||
- (NSWritingDirection) baseWritingDirection
|
||
{
|
||
return _baseDirection;
|
||
}
|
||
|
||
- (float) defaultTabInterval
|
||
{
|
||
return _defaultTabInterval;
|
||
}
|
||
|
||
- (float) lineHeightMultiple
|
||
{
|
||
return _lineHeightMultiple;
|
||
}
|
||
|
||
- (float) paragraphSpacingBefore
|
||
{
|
||
return _paragraphSpacingBefore;
|
||
}
|
||
|
||
- (int) headerLevel
|
||
{
|
||
return _headerLevel;
|
||
}
|
||
|
||
- (float) hyphenationFactor
|
||
{
|
||
return _hyphenationFactor;
|
||
}
|
||
|
||
- (NSArray *) textBlocks
|
||
{
|
||
return _textBlocks;
|
||
}
|
||
|
||
- (NSArray *) textLists
|
||
{
|
||
return _textLists;
|
||
}
|
||
|
||
- (float) tighteningFactorForTruncation
|
||
{
|
||
return _tighteningFactorForTruncation;
|
||
}
|
||
|
||
- (id) copyWithZone: (NSZone*)aZone
|
||
{
|
||
if (NSShouldRetainWithZone (self, aZone) == YES)
|
||
return RETAIN (self);
|
||
else
|
||
{
|
||
NSParagraphStyle *c;
|
||
|
||
c = (NSParagraphStyle*)NSCopyObject (self, 0, aZone);
|
||
c->_textBlocks = [_textBlocks mutableCopyWithZone: aZone];
|
||
c->_textLists = [_textLists mutableCopyWithZone: aZone];
|
||
return c;
|
||
}
|
||
}
|
||
|
||
- (id) mutableCopyWithZone: (NSZone*)aZone
|
||
{
|
||
NSMutableParagraphStyle *c;
|
||
|
||
c = [[NSMutableParagraphStyle allocWithZone: aZone] init];
|
||
[c setParagraphStyle: self];
|
||
return c;
|
||
}
|
||
|
||
- (id) initWithCoder: (NSCoder*)aCoder
|
||
{
|
||
if ([aCoder allowsKeyedCoding])
|
||
{
|
||
// TODO_NIB: Determine keys for NSParagraphStyle, if there are any.
|
||
}
|
||
else
|
||
{
|
||
unsigned count;
|
||
|
||
[aCoder decodeValueOfObjCType: @encode(int) at: &_alignment];
|
||
[aCoder decodeValueOfObjCType: @encode(int) at: &_lineBreakMode];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_firstLineHeadIndent];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_headIndent];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_lineSpacing];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_maximumLineHeight];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_minimumLineHeight];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_paragraphSpacing];
|
||
[aCoder decodeValueOfObjCType: @encode(float) at: &_tailIndent];
|
||
|
||
/*
|
||
* Tab stops don't conform to NSCoding - so we do it the long way.
|
||
*/
|
||
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
|
||
_tabStops = [[NSMutableArray alloc] initWithCapacity: count];
|
||
if (count > 0)
|
||
{
|
||
float locations[count];
|
||
NSTextTabType types[count];
|
||
unsigned i;
|
||
|
||
[aCoder decodeArrayOfObjCType: @encode(float)
|
||
count: count
|
||
at: locations];
|
||
[aCoder decodeArrayOfObjCType: @encode(int)
|
||
count: count
|
||
at: types];
|
||
for (i = 0; i < count; i++)
|
||
{
|
||
NSTextTab *tab;
|
||
|
||
tab = [[NSTextTab alloc] initWithType: types[i]
|
||
location: locations[i]];
|
||
[_tabStops addObject: tab];
|
||
RELEASE(tab);
|
||
}
|
||
}
|
||
|
||
if ([aCoder versionForClassName: @"NSParagraphStyle"] >= 2)
|
||
{
|
||
[aCoder decodeValueOfObjCType: @encode(int) at: &_baseDirection];
|
||
}
|
||
}
|
||
|
||
return self;
|
||
}
|
||
|
||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||
{
|
||
if ([aCoder allowsKeyedCoding])
|
||
{
|
||
// TODO_NIB: Determine keys for NSParagraphStyle, if there are any.
|
||
}
|
||
else
|
||
{
|
||
unsigned count;
|
||
|
||
[aCoder encodeValueOfObjCType: @encode(int) at: &_alignment];
|
||
[aCoder encodeValueOfObjCType: @encode(int) at: &_lineBreakMode];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_firstLineHeadIndent];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_headIndent];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_lineSpacing];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_maximumLineHeight];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_minimumLineHeight];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_paragraphSpacing];
|
||
[aCoder encodeValueOfObjCType: @encode(float) at: &_tailIndent];
|
||
|
||
/*
|
||
* Tab stops don't conform to NSCoding - so we do it the long way.
|
||
*/
|
||
count = [_tabStops count];
|
||
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
|
||
if (count > 0)
|
||
{
|
||
float locations[count];
|
||
NSTextTabType types[count];
|
||
unsigned i;
|
||
|
||
for (i = 0; i < count; i++)
|
||
{
|
||
NSTextTab *tab = [_tabStops objectAtIndex: i];
|
||
|
||
locations[i] = [tab location];
|
||
types[i] = [tab tabStopType];
|
||
}
|
||
[aCoder encodeArrayOfObjCType: @encode(float)
|
||
count: count
|
||
at: locations];
|
||
[aCoder encodeArrayOfObjCType: @encode(int)
|
||
count: count
|
||
at: types];
|
||
}
|
||
|
||
[aCoder encodeValueOfObjCType: @encode(int) at: &_baseDirection];
|
||
}
|
||
}
|
||
|
||
- (BOOL) isEqual: (id)aother
|
||
{
|
||
NSParagraphStyle *other = aother;
|
||
if (other == self)
|
||
return YES;
|
||
if ([other isKindOfClass: [NSParagraphStyle class]] == NO)
|
||
return NO;
|
||
|
||
#define C(x) if (x != other->x) return NO
|
||
C(_lineSpacing);
|
||
C(_paragraphSpacing);
|
||
C(_headIndent);
|
||
C(_tailIndent);
|
||
C(_firstLineHeadIndent);
|
||
C(_minimumLineHeight);
|
||
C(_maximumLineHeight);
|
||
C(_alignment);
|
||
C(_lineBreakMode);
|
||
C(_paragraphSpacingBefore);
|
||
C(_defaultTabInterval);
|
||
C(_hyphenationFactor);
|
||
C(_lineHeightMultiple);
|
||
C(_tighteningFactorForTruncation);
|
||
C(_headerLevel);
|
||
#undef C
|
||
|
||
return [_tabStops isEqualToArray: other->_tabStops];
|
||
}
|
||
|
||
- (NSUInteger) hash
|
||
{
|
||
return _alignment + _lineBreakMode;
|
||
}
|
||
|
||
|
||
@end
|
||
|
||
|
||
|
||
@implementation NSMutableParagraphStyle
|
||
|
||
+ (NSParagraphStyle*) defaultParagraphStyle
|
||
{
|
||
return AUTORELEASE ([[NSParagraphStyle defaultParagraphStyle] mutableCopy]);
|
||
}
|
||
|
||
- (void) setLineSpacing: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_lineSpacing = aFloat;
|
||
}
|
||
|
||
- (void) setParagraphSpacing: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_paragraphSpacing = aFloat;
|
||
}
|
||
|
||
- (void) setAlignment: (NSTextAlignment)newAlignment
|
||
{
|
||
_alignment = newAlignment;
|
||
}
|
||
|
||
- (void) setFirstLineHeadIndent: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_firstLineHeadIndent = aFloat;
|
||
}
|
||
|
||
- (void) setHeadIndent: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_headIndent = aFloat;
|
||
}
|
||
|
||
- (void) setTailIndent: (float)aFloat
|
||
{
|
||
_tailIndent = aFloat;
|
||
}
|
||
|
||
- (void) setLineBreakMode: (NSLineBreakMode)mode
|
||
{
|
||
_lineBreakMode = mode;
|
||
}
|
||
|
||
- (void) setMinimumLineHeight: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_minimumLineHeight = aFloat;
|
||
}
|
||
|
||
- (void) setMaximumLineHeight: (float)aFloat
|
||
{
|
||
NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
|
||
_maximumLineHeight = aFloat;
|
||
}
|
||
|
||
- (void) setBaseWritingDirection: (NSWritingDirection)direction
|
||
{
|
||
/*
|
||
* FIXME there is some confusion regarding natural writing direction.
|
||
*
|
||
* this method is documented as setting
|
||
* NSWritingDirectionLeftToRight or NSWritingDirectionRightToLeft
|
||
* based on the users language preferences.
|
||
* when encountering NSWritingDirectionNaturalDirection
|
||
*
|
||
* NSWritingDirectionNatural constant is documented as using the
|
||
* unicode bidi algorithm.
|
||
*
|
||
* no idea what the constant name or behaviour actually is.
|
||
*/
|
||
_baseDirection = direction;
|
||
}
|
||
|
||
- (void) setDefaultTabInterval: (float)interval
|
||
{
|
||
_defaultTabInterval = interval;
|
||
}
|
||
|
||
- (void) setLineHeightMultiple: (float)factor
|
||
{
|
||
_lineHeightMultiple = factor;
|
||
}
|
||
|
||
- (void) setParagraphSpacingBefore: (float)spacing
|
||
{
|
||
_paragraphSpacingBefore = spacing;
|
||
}
|
||
|
||
- (void) setHeaderLevel: (int)level
|
||
{
|
||
_headerLevel = level;
|
||
}
|
||
|
||
- (void) setHyphenationFactor: (float)factor
|
||
{
|
||
_hyphenationFactor = factor;
|
||
}
|
||
|
||
- (void) setTextBlocks: (NSArray *)blocks
|
||
{
|
||
ASSIGN(_textBlocks, blocks);
|
||
}
|
||
|
||
- (void) setTextLists: (NSArray *)lists
|
||
{
|
||
ASSIGN(_textLists, lists);
|
||
}
|
||
|
||
- (void) setTighteningFactorForTruncation: (float)factor
|
||
{
|
||
_tighteningFactorForTruncation = factor;
|
||
}
|
||
|
||
- (void) addTabStop: (NSTextTab*)anObject
|
||
{
|
||
unsigned count = [_tabStops count];
|
||
|
||
if (count == 0)
|
||
{
|
||
[_tabStops addObject: anObject];
|
||
}
|
||
else
|
||
{
|
||
while (count-- > 0)
|
||
{
|
||
NSTextTab *tab;
|
||
|
||
tab = [_tabStops objectAtIndex: count];
|
||
if ([tab compare: anObject] != NSOrderedDescending)
|
||
{
|
||
[_tabStops insertObject: anObject atIndex: count + 1];
|
||
return;
|
||
}
|
||
}
|
||
[_tabStops insertObject: anObject atIndex: 0];
|
||
}
|
||
}
|
||
|
||
- (void) removeTabStop: (NSTextTab*)anObject
|
||
{
|
||
unsigned i = [_tabStops indexOfObject: anObject];
|
||
|
||
if (i != NSNotFound)
|
||
[_tabStops removeObjectAtIndex: i];
|
||
}
|
||
|
||
- (void) setTabStops: (NSArray *)array
|
||
{
|
||
if (array != _tabStops)
|
||
{
|
||
[_tabStops removeAllObjects];
|
||
[_tabStops addObjectsFromArray: array];
|
||
[_tabStops sortUsingSelector: @selector(compare:)];
|
||
}
|
||
}
|
||
|
||
- (void) setParagraphStyle: (NSParagraphStyle*)obj
|
||
{
|
||
NSMutableParagraphStyle *p = (NSMutableParagraphStyle*)obj;
|
||
|
||
if (p == self)
|
||
return;
|
||
|
||
/* Can add tab stops without sorting as we know they are already sorted. */
|
||
[_tabStops removeAllObjects];
|
||
[_tabStops addObjectsFromArray: p->_tabStops];
|
||
|
||
if (p->_textBlocks)
|
||
[self setTextBlocks: p->_textBlocks];
|
||
if (p->_textLists)
|
||
[self setTextLists: p->_textLists];
|
||
|
||
_alignment = p->_alignment;
|
||
_firstLineHeadIndent = p->_firstLineHeadIndent;
|
||
_headIndent = p->_headIndent;
|
||
_lineBreakMode = p->_lineBreakMode;
|
||
_lineSpacing = p->_lineSpacing;
|
||
_maximumLineHeight = p->_maximumLineHeight;
|
||
_minimumLineHeight = p->_minimumLineHeight;
|
||
_paragraphSpacing = p->_paragraphSpacing;
|
||
_tailIndent = p->_tailIndent;
|
||
_baseDirection = p->_baseDirection;
|
||
_paragraphSpacingBefore = p->_paragraphSpacingBefore;
|
||
_defaultTabInterval = p->_defaultTabInterval;
|
||
_hyphenationFactor = p->_hyphenationFactor;
|
||
_lineHeightMultiple = p->_lineHeightMultiple;
|
||
_tighteningFactorForTruncation = p->_tighteningFactorForTruncation;
|
||
_headerLevel = p->_headerLevel;
|
||
}
|
||
|
||
- (id) copyWithZone: (NSZone*)aZone
|
||
{
|
||
NSMutableParagraphStyle *c;
|
||
|
||
c = (NSMutableParagraphStyle*)NSCopyObject (self, 0, aZone);
|
||
GSClassSwizzle(c, [NSParagraphStyle class]);
|
||
c->_tabStops = [_tabStops mutableCopyWithZone: aZone];
|
||
c->_textBlocks = [_textBlocks mutableCopyWithZone: aZone];
|
||
c->_textLists = [_textLists mutableCopyWithZone: aZone];
|
||
return c;
|
||
}
|
||
|
||
@end
|