Clean up layout invalidation. Set the prev pointer correctly when splitting a run during glyph invalidation.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@15990 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2003-02-17 20:30:26 +00:00
parent 1ba6d8c940
commit bdc3373174
4 changed files with 74 additions and 19 deletions

View file

@ -1,3 +1,15 @@
2003-02-17 21:25 Alexander Malmberg <alexander@malmberg.org>
* Headers/gnustep/gui/GSLayoutManager.h,
Headers/gnustep/gui/GSLayoutManager_internal.h,
Source/GSLayoutManager.m (-invalidateGlyphsForCharacterRange:
changeInLength:actualCharacterRange:): Set the prev pointer
correctly when splitting a run. Add sanity checks to catch try
to catch glyph structure corruption early.
(-textStorage:edited:range:changeInLength:invalidatedRange:): Clean
up layout invalidation.
2003-02-17 02:16 Alexander Malmberg <alexander@malmberg.org>
* Headers/gnustep/gui/GSLayoutManager.h, Source/GSLayoutManager.m:

View file

@ -148,6 +148,9 @@ If characters have been edited, lengthChange has the text length delta.
Mark the glyphs for the characters in aRange as invalid. lengthChange
is the text length delta. If not NULL, the range of characters actually
affected (_after_ the change) will be returned in actualRange.
This method is used internally and should _not_ be called. (It interacts
in complex ways with layout invalidation.)
*/
- (void) invalidateGlyphsForCharacterRange: (NSRange)aRange
changeInLength: (int)lengthChange
@ -248,6 +251,11 @@ manager might be substituting screen fonts. */
/** Layout **/
/*
This method is used internally and should _not_ be called. (It interacts
in complex ways with glyph invalidation, and with itself when doing soft
invalidation.)
*/
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange
isSoft: (BOOL)flag
actualCharacterRange: (NSRange *)actualRange;

View file

@ -193,6 +193,7 @@ typedef struct GSLayoutManager_textcontainer_s
-(void) _freeGlyphs;
-(void) _glyphDumpRuns;
-(void) _sanityChecks;
-(void) _generateGlyphsUpToCharacter: (unsigned int)last;
-(void) _generateGlyphsUpToGlyph: (unsigned int)last;

View file

@ -27,6 +27,7 @@
#include <AppKit/GSLayoutManager_internal.h>
#include <Foundation/NSCharacterSet.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <Foundation/NSValue.h>
@ -178,6 +179,20 @@ static int random_level(void)
}
-(void) _sanityChecks
{
glyph_run_t *g;
g = (glyph_run_t *)&glyphs[SKIP_LIST_DEPTH - 1];
while (g->head.next)
{
NSAssert((glyph_run_t *)((glyph_run_t *)g->head.next)->prev == g,
@"glyph structure corrupted: g->next->prev!=g");
g = (glyph_run_t *)g->head.next;
}
}
/* NSLayoutManager uses this is, so it can't be static (and since it isn't,
it needs a reasonably unique name). */
glyph_run_t *GSLayoutManager_run_for_glyph_index(unsigned int glyphIndex,
@ -927,8 +942,13 @@ it should still be safe. might lose opportunities to merge runs, though.
*/
cached_run = NULL;
/* [self _glyphDumpRuns];
printf("range=(%i+%i) lengthChange=%i\n", range.location, range.length, lengthChange);*/
/* Set it now for early returns. */
if (actualRange)
*actualRange = range;
// printf("range=(%i+%i) lengthChange=%i\n", range.location, range.length, lengthChange);
[self _sanityChecks];
//[self _glyphDumpRuns];
range.length -= lengthChange;
// printf("invalidate %i+%i=%i\n", range.location, range.length, range.location+range.length);
@ -1000,6 +1020,9 @@ it should still be safe. might lose opportunities to merge runs, though.
for (i = 1; i <= new->level; i++, hn--)
run_fix_head(hn);
if (new->head.next)
((glyph_run_t *)new->head.next)->prev = (glyph_run_head_t *)new;
r->head.char_length -= new->head.char_length;
}
@ -1104,8 +1127,8 @@ it should still be safe. might lose opportunities to merge runs, though.
trailing = !next;
}
/* printf("deleted\n");
[self _glyphDumpRuns];*/
// printf("deleted\n");
// [self _glyphDumpRuns];
/* r is the last run we want to keep, and the next run is the next
uninvalidated run. need to insert new runs for range */
@ -1126,7 +1149,7 @@ it should still be safe. might lose opportunities to merge runs, though.
inRange: NSMakeRange(0, [_textStorage length])];
/* printf("at %i, max=%i, effective range (%i+%i)\n",
ch, max, rng.location, rng.length); */
ch, max, rng.location, rng.length);*/
new = run_insert(context);
if (rng.location < ch)
@ -1173,6 +1196,7 @@ it should still be safe. might lose opportunities to merge runs, though.
*actualRange = range;
// [self _glyphDumpRuns];
[self _sanityChecks];
}
@ -1409,6 +1433,18 @@ it should still be safe. might lose opportunities to merge runs, though.
@implementation GSLayoutManager (layout)
/*
In the general case, we can't make any assumptions about how layout might
interact between line frag rects. To be safe in all cases, we must
invalidate all layout information.
TODO:
We could handle this by assuming that whoever calls this knows exactly what
needs to be invalidated. We won't be using it internally, anyway, so it
doesn't matter much to us, and it would make more advanced things possible
for external callers. On the other hand, it would be easy to break things
by calling this incorrectly.
*/
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange
isSoft: (BOOL)flag
actualCharacterRange: (NSRange *)actualRange
@ -1857,7 +1893,7 @@ forStartOfGlyphRange: (NSRange)glyphRange
return lf->used_rect;
}
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex: (unsigned int)glyphIndex
startLocation: (NSPoint *)p
{
int i;
@ -2285,6 +2321,11 @@ See [NSTextView -setTextContainer:] for more information about these calls.
}
/*
Note that NSLayoutManager completely overrides this (to perform more
intelligent invalidation of layout using the constraints on layout it
has).
*/
- (void) textStorage: (NSTextStorage *)aTextStorage
edited: (unsigned int)mask
range: (NSRange)range
@ -2296,23 +2337,16 @@ See [NSTextView -setTextContainer:] for more information about these calls.
if (!(mask & NSTextStorageEditedCharacters))
lengthChange = 0;
/* printf("edited: range=(%i+%i) invalidatedRange=(%i+%i) delta=%i\n",
range.location, range.length,
invalidatedRange.location, invalidatedRange.length,
lengthChange);*/
[self invalidateGlyphsForCharacterRange: invalidatedRange
changeInLength: lengthChange
actualCharacterRange: &r];
[self invalidateLayoutForCharacterRange: r
isSoft: NO
actualCharacterRange: &r];
r.location += r.length;
r.length = [_textStorage length] - r.location;
[self invalidateLayoutForCharacterRange: r
isSoft: YES
actualCharacterRange: NULL];
/*
See the comments above -invalidateLayoutForCharacterRange:isSoft:
actualCharacterRange: for information on why we invalidate everything
here.
*/
[self _invalidateLayoutFromContainer: 0];
[self _didInvalidateLayout];
}