1/** <title>NSParagraphStyle</title>
2
3   <abstract>NSParagraphStyle and NSMutableParagraphStyle hold paragraph style
4     information NSTextTab holds information about a single tab stop</abstract>
5
6   Copyright (C) 1996 Free Software Foundation, Inc.
7
8   Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
9   Date March 1999
10
11   This file is part of the GNUstep GUI Library.
12
13   This library is free software; you can redistribute it and/or
14   modify it under the terms of the GNU Lesser General Public
15   License as published by the Free Software Foundation; either
16   version 2 of the License, or (at your option) any later version.
17
18   This library is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
21   Lesser General Public License for more details.
22
23   You should have received a copy of the GNU Lesser General Public
24   License along with this library; see the file COPYING.LIB.
25   If not, see <http://www.gnu.org/licenses/> or write to the
26   Free Software Foundation, 51 Franklin Street, Fifth Floor,
27   Boston, MA 02110-1301, USA.
28*/
29
30#import <Foundation/NSDictionary.h>
31#import <Foundation/NSException.h>
32#import "AppKit/NSParagraphStyle.h"
33
34@implementation NSTextTab
35
36- (id) initWithType: (NSTextTabType)type location: (CGFloat)loc
37{
38  if ((self = [super init]))
39    {
40      _tabStopType = type;
41      _location = loc;
42      switch (type)
43        {
44          default:
45          case NSLeftTabStopType:
46            _alignment = NSLeftTextAlignment;
47            break;
48          case NSRightTabStopType:
49            _alignment = NSRightTextAlignment;
50            break;
51          case NSCenterTabStopType:
52            _alignment = NSCenterTextAlignment;
53            break;
54          case NSDecimalTabStopType:
55            _alignment = NSRightTextAlignment;
56            break;
57        }
58    }
59  return self;
60}
61
62- (id) initWithTextAlignment: (NSTextAlignment)align
63                    location: (CGFloat)loc
64                     options: (NSDictionary *)options
65{
66  NSTextTabType type;
67
68  switch (align)
69    {
70      default:
71      case NSLeftTextAlignment:
72	type = NSLeftTabStopType;
73	break;
74      case NSRightTextAlignment:
75	if ([options objectForKey: NSTabColumnTerminatorsAttributeName] != nil)
76	  {
77	    type = NSDecimalTabStopType;
78	  }
79	else
80	  {
81	    type = NSRightTabStopType;
82	  }
83	break;
84      case NSCenterTextAlignment:
85	type = NSCenterTabStopType;
86	break;
87      case NSJustifiedTextAlignment:
88	type = NSLeftTabStopType;
89	break;
90      case NSNaturalTextAlignment:
91	// FIXME: Get from language user setting
92	type = YES ? NSLeftTabStopType : NSRightTabStopType;
93	break;
94    }
95
96  if ((self = [self initWithType: type location: loc]))
97    {
98      _alignment = align;
99      ASSIGN(_options, options);
100    }
101  return self;
102}
103
104- (void) dealloc
105{
106  RELEASE(_options);
107  [super dealloc];
108}
109
110- (id) copyWithZone: (NSZone*)aZone
111{
112  NSTextTab *copy;
113
114  if (NSShouldRetainWithZone(self, aZone) == YES)
115    return RETAIN(self);
116
117  copy = (NSTextTab *)NSCopyObject(self, 0, aZone);
118  copy->_options = [_options copyWithZone: aZone];
119  return copy;
120}
121
122- (NSComparisonResult) compare: (id)anObject
123{
124  float	loc;
125
126  if (anObject == self)
127    return NSOrderedSame;
128  if (anObject == nil || ([anObject isKindOfClass: object_getClass(self)] == NO))
129    return NSOrderedAscending;
130  loc = ((NSTextTab*)anObject)->_location;
131  if (_location < loc)
132    return NSOrderedAscending;
133  else if (_location > loc)
134    return NSOrderedDescending;
135  else
136    return NSOrderedSame;
137}
138
139- (NSUInteger) hash
140{
141  NSUInteger val = (NSUInteger)_location;
142
143  val ^= (NSUInteger)_tabStopType;
144  return val;
145}
146
147- (BOOL) isEqual: (id)anObject
148{
149  if (anObject == self)
150    return YES;
151  if ([anObject isKindOfClass: object_getClass(self)] == NO)
152    return NO;
153  else if (((NSTextTab*)anObject)->_tabStopType != _tabStopType)
154    return NO;
155  else if (((NSTextTab*)anObject)->_location != _location)
156    return NO;
157  return YES;
158}
159
160- (CGFloat) location
161{
162  return _location;
163}
164
165- (NSTextTabType) tabStopType
166{
167  return _tabStopType;
168}
169- (NSTextAlignment) alignment
170{
171  return _alignment;
172}
173
174- (NSDictionary *) options
175{
176  return _options;
177}
178
179- (id) initWithCoder: (NSCoder *)aCoder
180{
181  if ([aCoder allowsKeyedCoding])
182    {
183      _location = [aCoder decodeFloatForKey: @"NSLocation"];
184    }
185  else
186    {
187      // FIXME
188    }
189  return self;
190}
191
192- (void) encodeWithCoder: (NSCoder *)aCoder
193{
194  if ([aCoder allowsKeyedCoding])
195    {
196      [aCoder encodeFloat: _location forKey: @"NSLocation"];
197    }
198  else
199    {
200      // FIXME
201    }
202}
203
204@end
205
206
207
208@implementation NSParagraphStyle
209
210static NSParagraphStyle	*defaultStyle = nil;
211
212+ (NSParagraphStyle*) defaultParagraphStyle
213{
214  if (defaultStyle == nil)
215    {
216      NSParagraphStyle	*style = [[self alloc] init];
217      /*
218      int		i;
219
220      for (i = 0; i < 12; i++)
221        {
222          NSTextTab	*tab;
223
224          tab = [[NSTextTab alloc] initWithType: NSLeftTabStopType
225                                   location: (i + 1) * 28.0];
226          [style->_tabStops addObject: tab];
227          RELEASE(tab);
228        }
229      */
230      defaultStyle = style;
231    }
232  return defaultStyle;
233}
234
235+ (void) initialize
236{
237  if (self == [NSParagraphStyle class])
238    {
239      /* Set the class version to 2, as the writing direction is now
240	 stored in the encoding */
241      [self setVersion: 3];
242    }
243}
244
245+ (NSWritingDirection) defaultWritingDirectionForLanguage: (NSString*) language
246{
247  static NSArray *rightToLeft;
248  NSWritingDirection writingDirection;
249  NSString *langCode = nil;
250
251  /* If language is 5/6 characters long with underscore in the middle,
252     treat it as ISO language-region format. */
253  if ([language length] == 5 && [language characterAtIndex: 2] == '_')
254      langCode = [language substringToIndex: 2];
255  else if ([language length] == 6 && [language characterAtIndex: 3] == '_')
256      langCode = [language substringToIndex: 3];
257  /* Else if it's just two or three chars long, treat as ISO 639 code. */
258  else if ([language length] == 2 || [language length] == 3)
259    langCode = language;
260
261  if (!rightToLeft)
262    // Holds languages whose current scripts are written right to left.
263    rightToLeft = [[NSArray alloc] initWithObjects: @"ar", @"ara", @"arc",
264				   @"chi", @"fa", @"fas", @"he", @"heb", @"iw",
265				   @"ji", @"kas", @"ks", @"ku", @"kur", @"pa",
266				   @"pan", @"per" @"ps", @"pus", @"sd", @"snd",
267				   @"syr", @"tk", @"tmh", @"tuk", @"ug",
268				   @"uig", @"ur," @"urd", @"yi", @"yid", @"zh",
269				   @"zho", nil];
270  if ([rightToLeft containsObject: langCode] == YES)
271    writingDirection = NSWritingDirectionRightToLeft;
272  else // If it's not RTL, assume LTR.
273    writingDirection = NSWritingDirectionLeftToRight;
274
275  return writingDirection;
276}
277
278- (void) dealloc
279{
280  if (self == defaultStyle)
281    {
282      NSLog(@"Argh - attempt to dealloc the default paragraph style!");
283      return;
284    }
285  RELEASE(_tabStops);
286  RELEASE(_textBlocks);
287  RELEASE(_textLists);
288  [super dealloc];
289}
290
291- (id) init
292{
293  if ((self = [super init]))
294    {
295      _alignment = NSNaturalTextAlignment;
296      //_firstLineHeadIndent = 0.0;
297      //_headIndent = 0.0;
298      _lineBreakMode = NSLineBreakByWordWrapping;
299      //_lineSpacing = 0.0;
300      //_maximumLineHeight = 0.0;
301      //_minimumLineHeight = 0.0;
302      //_paragraphSpacing = 0.0;
303      //_tailIndent = 0.0;
304      _baseDirection = NSWritingDirectionNaturalDirection;
305      _tabStops = [[NSMutableArray allocWithZone: [self zone]]
306                      initWithCapacity: 12];
307    }
308  return self;
309}
310
311- (NSString *)description
312{
313  return [NSString stringWithFormat:
314                     @"%@ Alignment: %ld LineSpacing: %f ParagraphSpacing: %f LineBreakMode: %ld",
315                   [super description], (long)_alignment, (float)_lineSpacing,
316                   (float)_paragraphSpacing, (long)_lineBreakMode];
317}
318
319/*
320 *      "Leading": distance between the bottom of one line fragment and top
321 *      of next (applied between lines in the same container).
322 *      Can't be negative. This value is included in the line fragment
323 *      heights in layout manager.
324 */
325- (CGFloat) lineSpacing
326{
327  return _lineSpacing;
328}
329
330/*
331 *      Distance between the bottom of this paragraph and top of next.
332 */
333- (CGFloat) paragraphSpacing
334{
335  return _paragraphSpacing;
336}
337
338- (NSTextAlignment) alignment
339{
340  return _alignment;
341}
342
343/*
344 *      The following values are relative to the appropriate margin
345 *      (depending on the paragraph direction)
346 */
347
348/*
349 *      Distance from margin to front edge of paragraph
350 */
351- (CGFloat) headIndent
352{
353  return _headIndent;
354}
355
356/*
357 *      Distance from margin to back edge of paragraph; if negative or 0,
358 *      from other margin
359 */
360- (CGFloat) tailIndent
361{
362  return _tailIndent;
363}
364
365/*
366 *      Distance from margin to edge appropriate for text direction
367 */
368- (CGFloat) firstLineHeadIndent
369{
370  return _firstLineHeadIndent;
371}
372
373/*
374 *      Distance from margin to tab stops
375 */
376- (NSArray *) tabStops
377{
378  return AUTORELEASE ([_tabStops copyWithZone: NSDefaultMallocZone ()]);
379}
380
381/*
382 *      Line height is the distance from bottom of descenders to to
383 *      of ascenders; basically the line fragment height. Does not include
384 *      lineSpacing (which is added after this computation).
385 */
386- (CGFloat) minimumLineHeight
387{
388  return _minimumLineHeight;
389}
390
391/*
392 *      0 implies no maximum.
393 */
394- (CGFloat) maximumLineHeight
395{
396  return _maximumLineHeight;
397}
398
399- (NSLineBreakMode) lineBreakMode
400{
401  return _lineBreakMode;
402}
403
404- (NSWritingDirection) baseWritingDirection
405{
406  return _baseDirection;
407}
408
409- (CGFloat) defaultTabInterval
410{
411  return _defaultTabInterval;
412}
413
414- (CGFloat) lineHeightMultiple
415{
416  return _lineHeightMultiple;
417}
418
419- (CGFloat) paragraphSpacingBefore
420{
421  return _paragraphSpacingBefore;
422}
423
424- (NSInteger) headerLevel
425{
426  return _headerLevel;
427}
428
429- (float) hyphenationFactor
430{
431  return _hyphenationFactor;
432}
433
434- (NSArray *) textBlocks
435{
436  return _textBlocks;
437}
438
439- (NSArray *) textLists
440{
441  return _textLists;
442}
443
444- (float) tighteningFactorForTruncation
445{
446  return _tighteningFactorForTruncation;
447}
448
449- (id) copyWithZone: (NSZone*)aZone
450{
451  if (NSShouldRetainWithZone (self, aZone) == YES)
452    return RETAIN (self);
453  else
454    {
455      NSParagraphStyle	*c;
456
457      c = (NSParagraphStyle*)NSCopyObject (self, 0, aZone);
458      c->_textBlocks = [_textBlocks mutableCopyWithZone: aZone];
459      c->_textLists = [_textLists mutableCopyWithZone: aZone];
460      return c;
461    }
462}
463
464- (id) mutableCopyWithZone: (NSZone*)aZone
465{
466  NSMutableParagraphStyle	*c;
467
468  c = [[NSMutableParagraphStyle allocWithZone: aZone] init];
469  [c setParagraphStyle: self];
470  return c;
471}
472
473- (id) initWithCoder: (NSCoder*)aCoder
474{
475  if ([aCoder allowsKeyedCoding])
476    {
477      _firstLineHeadIndent = [aCoder decodeFloatForKey: @"NSFirstLineHeadIndent"];
478      _headIndent = [aCoder decodeFloatForKey: @"NSHeadIndent"];
479      _paragraphSpacing = [aCoder decodeFloatForKey: @"NSParagraphSpacingBefore"];
480      ASSIGN(_tabStops, [aCoder decodeObjectForKey: @"NSTabStops"]);
481      ASSIGN(_textLists, [aCoder decodeObjectForKey: @"NSTextLists"]);
482      _baseDirection = [aCoder decodeIntForKey: @"NSWritingDirection"];
483    }
484  else
485    {
486      NSUInteger count;
487
488      [aCoder decodeValueOfObjCType: @encode(NSInteger) at: &_alignment];
489      [aCoder decodeValueOfObjCType: @encode(NSInteger) at: &_lineBreakMode];
490      [aCoder decodeValueOfObjCType: @encode(float) at: &_firstLineHeadIndent];
491      [aCoder decodeValueOfObjCType: @encode(float) at: &_headIndent];
492      [aCoder decodeValueOfObjCType: @encode(float) at: &_lineSpacing];
493      [aCoder decodeValueOfObjCType: @encode(float) at: &_maximumLineHeight];
494      [aCoder decodeValueOfObjCType: @encode(float) at: &_minimumLineHeight];
495      [aCoder decodeValueOfObjCType: @encode(float) at: &_paragraphSpacing];
496      [aCoder decodeValueOfObjCType: @encode(float) at: &_tailIndent];
497
498      /*
499       *	Tab stops don't conform to NSCoding - so we do it the long way.
500       */
501      [aCoder decodeValueOfObjCType: @encode(NSUInteger) at: &count];
502      _tabStops = [[NSMutableArray alloc] initWithCapacity: count];
503      if (count > 0)
504        {
505          float locations[count];
506          NSTextTabType types[count];
507          NSUInteger i;
508
509          [aCoder decodeArrayOfObjCType: @encode(float)
510                  count: count
511                  at: locations];
512          if ([aCoder versionForClassName: @"NSParagraphStyle"] >= 3)
513            {
514              [aCoder decodeArrayOfObjCType: @encode(NSInteger)
515                  count: count
516                  at: types];
517	    }
518	  else
519            {
520              [aCoder decodeArrayOfObjCType: @encode(int)
521                  count: count
522                  at: types];
523	    }
524          for (i = 0; i < count; i++)
525            {
526              NSTextTab	*tab;
527
528              tab = [[NSTextTab alloc] initWithType: types[i]
529                                       location: locations[i]];
530              [_tabStops addObject: tab];
531              RELEASE(tab);
532            }
533        }
534
535      if ([aCoder versionForClassName: @"NSParagraphStyle"] >= 2)
536        {
537          [aCoder decodeValueOfObjCType: @encode(NSInteger) at: &_baseDirection];
538        }
539    }
540
541  return self;
542}
543
544- (void) encodeWithCoder: (NSCoder*)aCoder
545{
546  if ([aCoder allowsKeyedCoding])
547    {
548      [aCoder encodeFloat: _firstLineHeadIndent forKey: @"NSFirstLineHeadIndent"];
549      [aCoder encodeFloat: _headIndent forKey: @"NSHeadIndent"];
550      [aCoder encodeFloat: _paragraphSpacing forKey: @"NSParagraphSpacingBefore"];
551      [aCoder encodeObject: _tabStops forKey: @"NSTabStops"];
552      [aCoder encodeObject: _textLists forKey: @"NSTextLists"];
553      [aCoder encodeInt: _baseDirection forKey: @"NSWritingDirection"];
554    }
555  else
556    {
557      NSUInteger count;
558
559      [aCoder encodeValueOfObjCType: @encode(NSInteger) at: &_alignment];
560      [aCoder encodeValueOfObjCType: @encode(NSInteger) at: &_lineBreakMode];
561      [aCoder encodeValueOfObjCType: @encode(float) at: &_firstLineHeadIndent];
562      [aCoder encodeValueOfObjCType: @encode(float) at: &_headIndent];
563      [aCoder encodeValueOfObjCType: @encode(float) at: &_lineSpacing];
564      [aCoder encodeValueOfObjCType: @encode(float) at: &_maximumLineHeight];
565      [aCoder encodeValueOfObjCType: @encode(float) at: &_minimumLineHeight];
566      [aCoder encodeValueOfObjCType: @encode(float) at: &_paragraphSpacing];
567      [aCoder encodeValueOfObjCType: @encode(float) at: &_tailIndent];
568
569      /*
570       *	Tab stops don't conform to NSCoding - so we do it the long way.
571       */
572      count = [_tabStops count];
573      [aCoder encodeValueOfObjCType: @encode(NSUInteger) at: &count];
574      if (count > 0)
575        {
576          float locations[count];
577          NSTextTabType types[count];
578          NSUInteger i;
579
580          for (i = 0; i < count; i++)
581            {
582              NSTextTab	*tab = [_tabStops objectAtIndex: i];
583
584              locations[i] = [tab location];
585              types[i] = [tab tabStopType];
586            }
587          [aCoder encodeArrayOfObjCType: @encode(float)
588                  count: count
589                  at: locations];
590          [aCoder encodeArrayOfObjCType: @encode(NSInteger)
591                  count: count
592                  at: types];
593        }
594
595      [aCoder encodeValueOfObjCType: @encode(NSInteger) at: &_baseDirection];
596    }
597}
598
599- (BOOL) isEqual: (id)aother
600{
601  NSParagraphStyle *other = aother;
602  if (other == self)
603    return YES;
604  if ([other isKindOfClass: [NSParagraphStyle class]] == NO)
605    return NO;
606
607#define C(x) if (x != other->x) return NO
608  C(_lineSpacing);
609  C(_paragraphSpacing);
610  C(_headIndent);
611  C(_tailIndent);
612  C(_firstLineHeadIndent);
613  C(_minimumLineHeight);
614  C(_maximumLineHeight);
615  C(_alignment);
616  C(_lineBreakMode);
617  C(_paragraphSpacingBefore);
618  C(_defaultTabInterval);
619  C(_hyphenationFactor);
620  C(_lineHeightMultiple);
621  C(_tighteningFactorForTruncation);
622  C(_headerLevel);
623#undef C
624
625  return [_tabStops isEqualToArray: other->_tabStops];
626}
627
628- (NSUInteger) hash
629{
630  return _alignment + _lineBreakMode;
631}
632
633
634@end
635
636
637
638@implementation NSMutableParagraphStyle
639
640+ (NSParagraphStyle*) defaultParagraphStyle
641{
642  return AUTORELEASE ([[NSParagraphStyle defaultParagraphStyle] mutableCopy]);
643}
644
645- (void) setLineSpacing: (CGFloat)aFloat
646{
647  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
648  _lineSpacing = aFloat;
649}
650
651- (void) setParagraphSpacing: (CGFloat)aFloat
652{
653  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
654  _paragraphSpacing = aFloat;
655}
656
657- (void) setAlignment: (NSTextAlignment)newAlignment
658{
659  _alignment = newAlignment;
660}
661
662- (void) setFirstLineHeadIndent: (CGFloat)aFloat
663{
664  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
665  _firstLineHeadIndent = aFloat;
666}
667
668- (void) setHeadIndent: (CGFloat)aFloat
669{
670  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
671  _headIndent = aFloat;
672}
673
674- (void) setTailIndent: (CGFloat)aFloat
675{
676  _tailIndent = aFloat;
677}
678
679- (void) setLineBreakMode: (NSLineBreakMode)mode
680{
681  _lineBreakMode = mode;
682}
683
684- (void) setMinimumLineHeight: (CGFloat)aFloat
685{
686  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
687  _minimumLineHeight = aFloat;
688}
689
690- (void) setMaximumLineHeight: (CGFloat)aFloat
691{
692  NSAssert (aFloat >= 0.0, NSInvalidArgumentException);
693  _maximumLineHeight = aFloat;
694}
695
696- (void) setBaseWritingDirection: (NSWritingDirection)direction
697{
698  /*
699   * FIXME there is some confusion regarding natural writing direction.
700   *
701   * this method is documented as setting
702   * NSWritingDirectionLeftToRight or NSWritingDirectionRightToLeft
703   * based on the users language preferences.
704   * when encountering NSWritingDirectionNaturalDirection
705   *
706   * NSWritingDirectionNatural constant is documented as using the
707   * unicode bidi algorithm.
708   *
709   * no idea what the constant name or behaviour actually is.
710   */
711  _baseDirection = direction;
712}
713
714- (void) setDefaultTabInterval: (CGFloat)interval
715{
716  _defaultTabInterval = interval;
717}
718
719- (void) setLineHeightMultiple: (CGFloat)factor
720{
721  _lineHeightMultiple = factor;
722}
723
724- (void) setParagraphSpacingBefore: (CGFloat)spacing
725{
726  _paragraphSpacingBefore = spacing;
727}
728
729- (void) setHeaderLevel: (NSInteger)level
730{
731  _headerLevel = level;
732}
733
734- (void) setHyphenationFactor: (float)factor
735{
736  _hyphenationFactor = factor;
737}
738
739- (void) setTextBlocks: (NSArray *)blocks
740{
741  ASSIGN(_textBlocks, blocks);
742}
743
744- (void) setTextLists: (NSArray *)lists
745{
746  ASSIGN(_textLists, lists);
747}
748
749- (void) setTighteningFactorForTruncation: (float)factor
750{
751  _tighteningFactorForTruncation = factor;
752}
753
754- (void) addTabStop: (NSTextTab*)anObject
755{
756  NSUInteger count = [_tabStops count];
757
758  if (count == 0)
759    {
760      [_tabStops addObject: anObject];
761    }
762  else
763    {
764      while (count-- > 0)
765	{
766	  NSTextTab *tab;
767
768	  tab = [_tabStops objectAtIndex: count];
769	  if ([tab compare: anObject] != NSOrderedDescending)
770	    {
771	      [_tabStops insertObject: anObject atIndex: count + 1];
772	      return;
773	    }
774	}
775      [_tabStops insertObject: anObject atIndex: 0];
776    }
777}
778
779- (void) removeTabStop: (NSTextTab*)anObject
780{
781  NSUInteger i = [_tabStops indexOfObject: anObject];
782
783  if (i != NSNotFound)
784    [_tabStops removeObjectAtIndex: i];
785}
786
787- (void) setTabStops: (NSArray *)array
788{
789  if (array != _tabStops)
790    {
791      [_tabStops removeAllObjects];
792      [_tabStops addObjectsFromArray: array];
793      [_tabStops sortUsingSelector: @selector(compare:)];
794    }
795}
796
797- (void) setParagraphStyle: (NSParagraphStyle*)obj
798{
799  NSMutableParagraphStyle *p = (NSMutableParagraphStyle*)obj;
800
801  if (p == self)
802    return;
803
804  /* Can add tab stops without sorting as we know they are already sorted. */
805  [_tabStops removeAllObjects];
806  [_tabStops addObjectsFromArray: p->_tabStops];
807
808  if (p->_textBlocks)
809    [self setTextBlocks: p->_textBlocks];
810  if (p->_textLists)
811    [self setTextLists: p->_textLists];
812
813  _alignment = p->_alignment;
814  _firstLineHeadIndent = p->_firstLineHeadIndent;
815  _headIndent = p->_headIndent;
816  _lineBreakMode = p->_lineBreakMode;
817  _lineSpacing = p->_lineSpacing;
818  _maximumLineHeight = p->_maximumLineHeight;
819  _minimumLineHeight = p->_minimumLineHeight;
820  _paragraphSpacing = p->_paragraphSpacing;
821  _tailIndent = p->_tailIndent;
822  _baseDirection = p->_baseDirection;
823  _paragraphSpacingBefore = p->_paragraphSpacingBefore;
824  _defaultTabInterval = p->_defaultTabInterval;
825  _hyphenationFactor = p->_hyphenationFactor;
826  _lineHeightMultiple = p->_lineHeightMultiple;
827  _tighteningFactorForTruncation = p->_tighteningFactorForTruncation;
828  _headerLevel = p->_headerLevel;
829}
830
831- (id) copyWithZone: (NSZone*)aZone
832{
833  NSMutableParagraphStyle *c;
834
835  c = (NSMutableParagraphStyle*)NSCopyObject (self, 0, aZone);
836  GSClassSwizzle(c, [NSParagraphStyle class]);
837  c->_tabStops = [_tabStops mutableCopyWithZone: aZone];
838  c->_textBlocks = [_textBlocks mutableCopyWithZone: aZone];
839  c->_textLists = [_textLists mutableCopyWithZone: aZone];
840  return c;
841}
842
843@end
844