Renamed the ivars of _GNULineLayoutInfo to correspond to those of

GSLineLayoutInfo. Call a few more abstract methods. Added
AutoreleasePool in [rebuildForRange:delta:inTextContainer:] to free
up memory.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8081 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
FredKiefer 2000-11-12 13:54:54 +00:00
parent 1a984aad2b
commit e7dc2366c4

View file

@ -59,8 +59,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
@interface _GNULineLayoutInfo: NSObject @interface _GNULineLayoutInfo: NSObject
{ {
@public @public
NSRange lineRange; NSRange glyphRange;
NSRect lineRect; NSRect lineFragmentRect;
NSRect usedRect; NSRect usedRect;
} }
@ -70,8 +70,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
usedRect: (NSRect)charRect; usedRect: (NSRect)charRect;
- (NSRange) lineRange; - (NSRange) glyphRange;
- (NSRect) lineRect; - (NSRect) lineFragmentRect;
- (NSString*) description; - (NSString*) description;
@end @end
@ -84,27 +84,27 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
_GNULineLayoutInfo *ret = AUTORELEASE([_GNULineLayoutInfo new]); _GNULineLayoutInfo *ret = AUTORELEASE([_GNULineLayoutInfo new]);
ret->lineRange = aRange; ret->glyphRange = aRange;
ret->lineRect = aRect; ret->lineFragmentRect = aRect;
ret->usedRect = charRect; ret->usedRect = charRect;
return ret; return ret;
} }
- (NSRange) lineRange - (NSRange) glyphRange
{ {
return lineRange; return glyphRange;
} }
- (NSRect) lineRect - (NSRect) lineFragmentRect
{ {
return lineRect; return lineFragmentRect;
} }
- (NSString*) description - (NSString*) description
{ {
return [[NSDictionary dictionaryWithObjectsAndKeys: return [[NSDictionary dictionaryWithObjectsAndKeys:
NSStringFromRange(lineRange), @"LineRange", NSStringFromRange(glyphRange), @"GlyphRange",
NSStringFromRect(lineRect), @"LineRect", NSStringFromRect(lineFragmentRect), @"LineFragmentRect",
nil] nil]
description]; description];
} }
@ -202,7 +202,7 @@ static NSCharacterSet *invSelectionWordGranularitySet;
objectAtIndex: objectAtIndex:
[self lineLayoutIndexForPoint: point]]; [self lineLayoutIndexForPoint: point]];
NSRect rect = currentInfo->usedRect; NSRect rect = currentInfo->usedRect;
NSRange range = currentInfo->lineRange; NSRange range = currentInfo->glyphRange;
int i; int i;
int min = range.location; int min = range.location;
int max = NSMaxRange(range); int max = NSMaxRange(range);
@ -264,9 +264,9 @@ static NSCharacterSet *invSelectionWordGranularitySet;
index]]; index]];
if (lineFragmentRange) if (lineFragmentRange)
*lineFragmentRange = currentInfo->lineRange; *lineFragmentRange = currentInfo->glyphRange;
return currentInfo->lineRect; return currentInfo->lineFragmentRect;
} }
- (NSPoint)locationForGlyphAtIndex:(unsigned)index - (NSPoint)locationForGlyphAtIndex:(unsigned)index
@ -284,11 +284,11 @@ static NSCharacterSet *invSelectionWordGranularitySet;
currentInfo = [_lineLayoutInformation currentInfo = [_lineLayoutInformation
objectAtIndex: [self lineLayoutIndexForGlyphIndex: objectAtIndex: [self lineLayoutIndexForGlyphIndex:
index]]; index]];
if (index >= NSMaxRange(currentInfo->lineRange)) if (index >= NSMaxRange(currentInfo->glyphRange))
return NSMakePoint(NSMaxX(currentInfo->usedRect), 0); return NSMakePoint(NSMaxX(currentInfo->usedRect), 0);
start = currentInfo->lineRange.location; start = currentInfo->glyphRange.location;
rect = currentInfo->lineRect; rect = currentInfo->lineFragmentRect;
x = [self _sizeOfRange: NSMakeRange(start, index-start)].width; x = [self _sizeOfRange: NSMakeRange(start, index-start)].width;
return NSMakePoint(x, 0); return NSMakePoint(x, 0);
@ -399,12 +399,26 @@ static NSCharacterSet *invSelectionWordGranularitySet;
return NSMakeRange(0, [_textStorage length]); return NSMakeRange(0, [_textStorage length]);
} }
- (NSTextContainer*) textContainerForGlyphAtIndex: (unsigned)glyphIndex
effectiveRange: (NSRange*)effectiveRange
{
if (effectiveRange)
*effectiveRange = NSMakeRange(0, [_textStorage length]);
return [_textContainers objectAtIndex: 0];
}
- (void) setTextContainer: (NSTextContainer*)aTextContainer
forGlyphRange: (NSRange)glyphRange
{
}
- (void)invalidateGlyphsForCharacterRange:(NSRange)charRange - (void)invalidateGlyphsForCharacterRange:(NSRange)charRange
changeInLength:(int)delta changeInLength:(int)delta
actualCharacterRange:(NSRange*)actualCharRange actualCharacterRange:(NSRange*)actualCharRange
{ {
// As we currenty dont have any glyph character mapping, we only have // As we currenty dont have any glyph character mapping, we only have
// to ajust the ranges in the line layout infos // to adjust the ranges in the line layout infos
if (actualCharRange) if (actualCharRange)
*actualCharRange = charRange; *actualCharRange = charRange;
@ -415,7 +429,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
actualCharacterRange: (NSRange*)actualRange actualCharacterRange: (NSRange*)actualRange
{ {
NSRange lineRange; NSRange lineRange;
NSTextContainer *aTextContainer = [_textContainers objectAtIndex: 0]; NSTextContainer *aTextContainer = [self textContainerForGlyphAtIndex: aRange.location
effectiveRange: NULL];
lineRange = [self rebuildForRange: aRange lineRange = [self rebuildForRange: aRange
delta: 0 delta: 0
@ -433,16 +448,18 @@ static NSCharacterSet *invSelectionWordGranularitySet;
invalidatedRange:(NSRange)invalidatedCharRange; invalidatedRange:(NSRange)invalidatedCharRange;
{ {
NSRange lineRange; NSRange lineRange;
NSTextContainer *aTextContainer = [_textContainers objectAtIndex: 0]; NSTextContainer *aTextContainer;
// No editing // No editing
if (!mask) if (!mask)
return; return;
[self invalidateGlyphsForCharacterRange: invalidatedCharRange [self invalidateGlyphsForCharacterRange: invalidatedCharRange
changeInLength: delta changeInLength: delta
actualCharacterRange: NULL]; actualCharacterRange: NULL];
aTextContainer = [self textContainerForGlyphAtIndex: aRange.location
effectiveRange: NULL];
lineRange = [self rebuildForRange: aRange lineRange = [self rebuildForRange: aRange
delta: delta delta: delta
inTextContainer: aTextContainer]; inTextContainer: aTextContainer];
@ -456,7 +473,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
- (void)drawBackgroundForGlyphRange:(NSRange)glyphRange - (void)drawBackgroundForGlyphRange:(NSRange)glyphRange
atPoint:(NSPoint)containerOrigin atPoint:(NSPoint)containerOrigin
{ {
NSTextContainer *aTextContainer = [_textContainers objectAtIndex: 0]; NSTextContainer *aTextContainer = [self textContainerForGlyphAtIndex: glyphRange.location
effectiveRange: NULL];
NSRect rect = [self boundingRectForGlyphRange: glyphRange NSRect rect = [self boundingRectForGlyphRange: glyphRange
inTextContainer: aTextContainer]; inTextContainer: aTextContainer];
@ -498,6 +516,11 @@ static NSCharacterSet *invSelectionWordGranularitySet;
usedRect: usedRect]]; usedRect: usedRect]];
} }
- (void) setLocation: (NSPoint)aPoint
forStartOfGlyphRange: (NSRange)glyphRange
{
}
@end @end
@implementation GSSimpleLayoutManager (Private) @implementation GSSimpleLayoutManager (Private)
@ -523,8 +546,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
int min = 0; int min = 0;
int max = MAX(0, [_lineLayoutInformation count] - 1); int max = MAX(0, [_lineLayoutInformation count] - 1);
float y = point.y; float y = point.y;
float fmin = NSMinY([[_lineLayoutInformation objectAtIndex: 0] lineRect]); float fmin = NSMinY([[_lineLayoutInformation objectAtIndex: 0] lineFragmentRect]);
float fmax = NSMaxY([[_lineLayoutInformation lastObject] lineRect]); float fmax = NSMaxY([[_lineLayoutInformation lastObject] lineFragmentRect]);
NSRect rect; NSRect rect;
if (y >= fmax) if (y >= fmax)
@ -539,7 +562,7 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
_GNULineLayoutInfo *ci = [_lineLayoutInformation objectAtIndex: i]; _GNULineLayoutInfo *ci = [_lineLayoutInformation objectAtIndex: i];
rect = ci->lineRect; rect = ci->lineFragmentRect;
if (NSMaxY(rect) < y) if (NSMaxY(rect) < y)
{ {
@ -565,8 +588,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
int min = 0; int min = 0;
int max = MAX(0, [_lineLayoutInformation count] - 1); int max = MAX(0, [_lineLayoutInformation count] - 1);
unsigned y = anIndex; unsigned y = anIndex;
unsigned fmin = [[_lineLayoutInformation objectAtIndex: 0] lineRange].location; unsigned fmin = [[_lineLayoutInformation objectAtIndex: 0] glyphRange].location;
unsigned fmax = NSMaxRange([[_lineLayoutInformation lastObject] lineRange]); unsigned fmax = NSMaxRange([[_lineLayoutInformation lastObject] glyphRange]);
NSRange range; NSRange range;
if (y >= fmax) if (y >= fmax)
@ -581,7 +604,7 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
_GNULineLayoutInfo *ci = [_lineLayoutInformation objectAtIndex: i]; _GNULineLayoutInfo *ci = [_lineLayoutInformation objectAtIndex: i];
range = ci->lineRange; range = ci->glyphRange;
if (NSMaxRange(range) <= y) if (NSMaxRange(range) <= y)
{ {
@ -613,13 +636,13 @@ static NSCharacterSet *invSelectionWordGranularitySet;
currentInfo = [_lineLayoutInformation lastObject]; currentInfo = [_lineLayoutInformation lastObject];
else else
currentInfo = [_lineLayoutInformation objectAtIndex: startLine]; currentInfo = [_lineLayoutInformation objectAtIndex: startLine];
startIndex = currentInfo->lineRange.location; startIndex = currentInfo->glyphRange.location;
if (endLine >= [_lineLayoutInformation count]) if (endLine >= [_lineLayoutInformation count])
currentInfo = [_lineLayoutInformation lastObject]; currentInfo = [_lineLayoutInformation lastObject];
else else
currentInfo = [_lineLayoutInformation objectAtIndex: endLine]; currentInfo = [_lineLayoutInformation objectAtIndex: endLine];
endIndex = NSMaxRange(currentInfo->lineRange); endIndex = NSMaxRange(currentInfo->glyphRange);
return NSMakeRange(startIndex, endIndex - startIndex); return NSMakeRange(startIndex, endIndex - startIndex);
} }
@ -627,7 +650,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
// rect to the end of line // rect to the end of line
- (NSRect) rectForCharacterIndex: (unsigned)index - (NSRect) rectForCharacterIndex: (unsigned)index
{ {
float width = [[_textContainers objectAtIndex: 0] containerSize].width; float width = [[self textContainerForGlyphAtIndex: index
effectiveRange: NULL] containerSize].width;
_GNULineLayoutInfo *currentInfo; _GNULineLayoutInfo *currentInfo;
unsigned start; unsigned start;
NSRect rect; NSRect rect;
@ -639,9 +663,9 @@ static NSCharacterSet *invSelectionWordGranularitySet;
} }
currentInfo = [_lineLayoutInformation lastObject]; currentInfo = [_lineLayoutInformation lastObject];
if (index >= NSMaxRange(currentInfo->lineRange)) if (index >= NSMaxRange(currentInfo->glyphRange))
{ {
NSRect rect = currentInfo->lineRect; NSRect rect = currentInfo->lineFragmentRect;
return NSMakeRect(NSMaxX (rect), rect.origin.y, return NSMakeRect(NSMaxX (rect), rect.origin.y,
width - NSMaxX (rect), width - NSMaxX (rect),
@ -652,8 +676,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
currentInfo = [_lineLayoutInformation currentInfo = [_lineLayoutInformation
objectAtIndex: [self lineLayoutIndexForGlyphIndex: objectAtIndex: [self lineLayoutIndexForGlyphIndex:
index]]; index]];
start = currentInfo->lineRange.location; start = currentInfo->glyphRange.location;
rect = currentInfo->lineRect; rect = currentInfo->lineFragmentRect;
x = rect.origin.x + [self _sizeOfRange: NSMakeRange(start, index-start)].width; x = rect.origin.x + [self _sizeOfRange: NSMakeRange(start, index-start)].width;
return NSMakeRect(x, rect.origin.y, NSMaxX (rect) - x, return NSMakeRect(x, rect.origin.y, NSMaxX (rect) - x,
@ -664,9 +688,11 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
int i; int i;
unsigned count; unsigned count;
NSTextContainer *aTextContainer = [self textContainerForGlyphAtIndex: aRange.location
effectiveRange: NULL];
NSRect *rects = [self rectArrayForCharacterRange: aRange NSRect *rects = [self rectArrayForCharacterRange: aRange
withinSelectedCharacterRange: aRange withinSelectedCharacterRange: aRange
inTextContainer: [_textContainers objectAtIndex: 0] inTextContainer: aTextContainer
rectCount: &count]; rectCount: &count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -699,8 +725,8 @@ static NSCharacterSet *invSelectionWordGranularitySet;
for ((lineEnum = [linesToDraw objectEnumerator]); for ((lineEnum = [linesToDraw objectEnumerator]);
(currentInfo = [lineEnum nextObject]);) (currentInfo = [lineEnum nextObject]);)
{ {
[_textStorage drawRange: currentInfo->lineRange [_textStorage drawRange: currentInfo->glyphRange
inRect: currentInfo->lineRect]; inRect: currentInfo->lineFragmentRect];
} }
} }
@ -713,14 +739,14 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
_GNULineLayoutInfo *firstInfo _GNULineLayoutInfo *firstInfo
= [_lineLayoutInformation objectAtIndex: redrawLineRange.location]; = [_lineLayoutInformation objectAtIndex: redrawLineRange.location];
NSRect displayRect = firstInfo->lineRect; NSRect displayRect = firstInfo->lineFragmentRect;
float width = [aTextContainer containerSize].width; float width = [aTextContainer containerSize].width;
if (redrawLineRange.length > 1) if (redrawLineRange.length > 1)
displayRect = NSUnionRect(displayRect, displayRect = NSUnionRect(displayRect,
[[_lineLayoutInformation [[_lineLayoutInformation
objectAtIndex: objectAtIndex:
(int)NSMaxRange(redrawLineRange) - 1] lineRect]); (int)NSMaxRange(redrawLineRange) - 1] lineFragmentRect]);
displayRect.size.width = width - displayRect.origin.x; displayRect.size.width = width - displayRect.origin.x;
[[aTextContainer textView] setNeedsDisplayInRect: displayRect]; [[aTextContainer textView] setNeedsDisplayInRect: displayRect];
@ -733,7 +759,7 @@ static NSCharacterSet *invSelectionWordGranularitySet;
{ {
_GNULineLayoutInfo *lastInfo = [_lineLayoutInformation lastObject]; _GNULineLayoutInfo *lastInfo = [_lineLayoutInformation lastObject];
// The start character in the ghostArray // The start character in the ghostArray
unsigned nextChar = NSMaxRange(lastInfo->lineRange) - relocOffset; unsigned nextChar = NSMaxRange(lastInfo->glyphRange) - relocOffset;
NSEnumerator *relocEnum; NSEnumerator *relocEnum;
_GNULineLayoutInfo *currReloc = nil; _GNULineLayoutInfo *currReloc = nil;
float yReloc; float yReloc;
@ -743,7 +769,7 @@ static NSCharacterSet *invSelectionWordGranularitySet;
unsigned firstChar; unsigned firstChar;
currReloc = [ghostArray objectAtIndex: 0]; currReloc = [ghostArray objectAtIndex: 0];
firstChar = currReloc->lineRange.location; firstChar = currReloc->glyphRange.location;
if (firstChar == nextChar) if (firstChar == nextChar)
break; break;
else if (firstChar > nextChar) else if (firstChar > nextChar)
@ -756,16 +782,16 @@ static NSCharacterSet *invSelectionWordGranularitySet;
return NO; return NO;
relocEnum = [ghostArray objectEnumerator]; relocEnum = [ghostArray objectEnumerator];
yReloc = NSMaxY(lastInfo->lineRect) - currReloc->lineRect.origin.y; yReloc = NSMaxY(lastInfo->lineFragmentRect) - currReloc->lineFragmentRect.origin.y;
if (yDisplacement) if (yDisplacement)
*yDisplacement = yReloc; *yDisplacement = yReloc;
while ((currReloc = [relocEnum nextObject]) != nil) while ((currReloc = [relocEnum nextObject]) != nil)
{ {
currReloc->lineRange.location += relocOffset; currReloc->glyphRange.location += relocOffset;
if (yReloc) if (yReloc)
{ {
currReloc->lineRect.origin.y += yReloc; currReloc->lineFragmentRect.origin.y += yReloc;
currReloc->usedRect.origin.y += yReloc; currReloc->usedRect.origin.y += yReloc;
} }
[_lineLayoutInformation addObject: currReloc]; [_lineLayoutInformation addObject: currReloc];
@ -791,8 +817,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
return NSMakeRange(start, end - start); return NSMakeRange(start, end - start);
} }
// begin: central line formatting method--------------------------------------- // returns range of lines actually updated
// returns count of lines actually updated
- (NSRange) rebuildForRange: (NSRange)aRange - (NSRange) rebuildForRange: (NSRange)aRange
delta: (int)insertionDelta delta: (int)insertionDelta
inTextContainer:(NSTextContainer *)aTextContainer inTextContainer:(NSTextContainer *)aTextContainer
@ -831,9 +856,9 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
{ {
_GNULineLayoutInfo *lastValidLineInfo = [_lineLayoutInformation _GNULineLayoutInfo *lastValidLineInfo = [_lineLayoutInformation
objectAtIndex: aLine - 1]; objectAtIndex: aLine - 1];
NSRect aRect = lastValidLineInfo->lineRect; NSRect aRect = lastValidLineInfo->lineFragmentRect;
startingIndex = NSMaxRange(lastValidLineInfo->lineRange); startingIndex = NSMaxRange(lastValidLineInfo->glyphRange);
drawingPoint = aRect.origin; drawingPoint = aRect.origin;
drawingPoint.y += aRect.size.height; drawingPoint.y += aRect.size.height;
} }
@ -888,12 +913,16 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
lScanner = [NSScanner scannerWithString: paragraph]; lScanner = [NSScanner scannerWithString: paragraph];
[lScanner setCharactersToBeSkipped: nil]; [lScanner setCharactersToBeSkipped: nil];
// Process a paragraph
do do
{ {
// Temporary added a autorelease pool, as the current layout mechnism
// uses up much memory space, that should be freed as soon as possible.
CREATE_AUTORELEASE_POOL(pool);
NSRect fragmentRect; NSRect fragmentRect;
NSRect usedLineRect; NSRect usedLineRect;
float width; float width;
NSRange currentLineRange; NSRange lineGlyphRange;
// starts with zero, do not confuse with startingLineCharIndex // starts with zero, do not confuse with startingLineCharIndex
unsigned localLineStartIndex = [lScanner scanLocation]; unsigned localLineStartIndex = [lScanner scanLocation];
unsigned scannerPosition = localLineStartIndex; unsigned scannerPosition = localLineStartIndex;
@ -1012,18 +1041,30 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
} }
} }
currentLineRange = NSMakeRange (startingLineCharIndex, lineGlyphRange = NSMakeRange (startingLineCharIndex,
scannerPosition - localLineStartIndex); scannerPosition - localLineStartIndex);
// Adjust the height of the line fragment rect, as this will the to big // Adjust the height of the line fragment rect, as this will the to big
fragmentRect.size.height = usedLineRect.size.height; fragmentRect.size.height = usedLineRect.size.height;
// This range is to small, as there are more lines that fit into the container
[self setTextContainer: aTextContainer
forGlyphRange: lineGlyphRange];
[self setLineFragmentRect: fragmentRect [self setLineFragmentRect: fragmentRect
forGlyphRange: currentLineRange forGlyphRange: lineGlyphRange
usedRect: usedLineRect]; usedRect: usedLineRect];
// This range is too big, as there are different runs in the glyph range
[self setLocation: NSMakePoint(0.0, 0.0)
forStartOfGlyphRange: lineGlyphRange];
currentLineIndex++; currentLineIndex++;
startingLineCharIndex = NSMaxRange(currentLineRange); startingLineCharIndex = NSMaxRange(lineGlyphRange);
drawingPoint.y += usedLineRect.size.height; drawingPoint.y += usedLineRect.size.height;
drawingPoint.x = 0; drawingPoint.x = 0;
RELEASE(pool);
if (ghostArray != nil) if (ghostArray != nil)
{ {
float yDisplacement = 0; float yDisplacement = 0;
@ -1056,7 +1097,5 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
// lines actually updated (optimized drawing) // lines actually updated (optimized drawing)
return NSMakeRange(aLine, MAX(1, [_lineLayoutInformation count] - aLine)); return NSMakeRange(aLine, MAX(1, [_lineLayoutInformation count] - aLine));
} }
// end: central line formatting method------------------------------------
@end @end