Skip to content

Problems with NSTextList and NSParagraphStyle isEqual: implementations #294

@fjmilens3

Description

@fjmilens3

The implementation of isEqual: for NSTextList and NSParagraphStyle needs to be reconsidered. As a practical matter it causes problems with list handling in NSTextViews/NSTextStorage.

(I'd also be happy to submit some PRs on these if nobody else is interested, but at this time, I've just started playing with GNUStep and don't have it building locally. The three issues I'm reporting are all interrelated to some degree in terms of their effects.)

NSTextList

For NSTextList on GNUStep, we do the following and compare some of the member fields:

- (BOOL) isEqual: (id)anObject
{
if (anObject == self)
{
return YES;
}
if (anObject == nil || [anObject isKindOfClass: [NSTextList class]] == NO)
{
return NO;
}
return ([anObject listOptions] == _listOptions)
&& [_markerFormat isEqualToString: [anObject markerFormat]];
}

On the other hand, Cocoa itself seems to treat each NSTextList as unique, even if they have the same values:

NSTextList *list1 = [[NSTextList alloc] initWithMarkerFormat: @"{box}" options:0];
NSTextList *list2 = [[NSTextList alloc] initWithMarkerFormat: @"{box}" options:0];

NSLog(@"Equals: %d", [list1 isEqual: list2]);

On Cocoa this prints 0 but on GNUStep it prints 1. I suspect the Cocoa implementation's isEqual: only looks to see if they're the exact same object, which makes sense. Two lists might have the same values (marker format, starting value) but they would still be fundamentally different lists. (This also relates to the below topic.)

NSParagraphStyle

For NSParagraphStyle it currently doesn't include the textLists as part of the equality test:

- (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];
}

That appears to be causing a problem where NSParagraphStyle runs in attributed strings get merged together when they shouldn't. In this case it can happen when adjacent paragraph styles differing only by lists end up getting combined when they shouldn't, but it could conceivably happen in other situations as well (text blocks perhaps?).

Note that adding the textLists to the comparison here won't have any effect unless the NSTextList comparison itself is fixed to treat each instance as unique.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions