mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 19:50:48 +00:00
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:
parent
901b07f83e
commit
428737c6d4
4 changed files with 74 additions and 19 deletions
12
ChangeLog
12
ChangeLog
|
@ -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>
|
2003-02-17 02:16 Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
|
||||||
* Headers/gnustep/gui/GSLayoutManager.h, Source/GSLayoutManager.m:
|
* Headers/gnustep/gui/GSLayoutManager.h, Source/GSLayoutManager.m:
|
||||||
|
|
|
@ -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
|
Mark the glyphs for the characters in aRange as invalid. lengthChange
|
||||||
is the text length delta. If not NULL, the range of characters actually
|
is the text length delta. If not NULL, the range of characters actually
|
||||||
affected (_after_ the change) will be returned in actualRange.
|
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
|
- (void) invalidateGlyphsForCharacterRange: (NSRange)aRange
|
||||||
changeInLength: (int)lengthChange
|
changeInLength: (int)lengthChange
|
||||||
|
@ -248,6 +251,11 @@ manager might be substituting screen fonts. */
|
||||||
|
|
||||||
/** Layout **/
|
/** 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
|
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange
|
||||||
isSoft: (BOOL)flag
|
isSoft: (BOOL)flag
|
||||||
actualCharacterRange: (NSRange *)actualRange;
|
actualCharacterRange: (NSRange *)actualRange;
|
||||||
|
|
|
@ -193,6 +193,7 @@ typedef struct GSLayoutManager_textcontainer_s
|
||||||
-(void) _freeGlyphs;
|
-(void) _freeGlyphs;
|
||||||
|
|
||||||
-(void) _glyphDumpRuns;
|
-(void) _glyphDumpRuns;
|
||||||
|
-(void) _sanityChecks;
|
||||||
|
|
||||||
-(void) _generateGlyphsUpToCharacter: (unsigned int)last;
|
-(void) _generateGlyphsUpToCharacter: (unsigned int)last;
|
||||||
-(void) _generateGlyphsUpToGlyph: (unsigned int)last;
|
-(void) _generateGlyphsUpToGlyph: (unsigned int)last;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <AppKit/GSLayoutManager_internal.h>
|
#include <AppKit/GSLayoutManager_internal.h>
|
||||||
|
|
||||||
#include <Foundation/NSCharacterSet.h>
|
#include <Foundation/NSCharacterSet.h>
|
||||||
|
#include <Foundation/NSDebug.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSValue.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,
|
/* NSLayoutManager uses this is, so it can't be static (and since it isn't,
|
||||||
it needs a reasonably unique name). */
|
it needs a reasonably unique name). */
|
||||||
glyph_run_t *GSLayoutManager_run_for_glyph_index(unsigned int glyphIndex,
|
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;
|
cached_run = NULL;
|
||||||
|
|
||||||
/* [self _glyphDumpRuns];
|
/* Set it now for early returns. */
|
||||||
printf("range=(%i+%i) lengthChange=%i\n", range.location, range.length, lengthChange);*/
|
if (actualRange)
|
||||||
|
*actualRange = range;
|
||||||
|
|
||||||
|
// printf("range=(%i+%i) lengthChange=%i\n", range.location, range.length, lengthChange);
|
||||||
|
[self _sanityChecks];
|
||||||
|
//[self _glyphDumpRuns];
|
||||||
range.length -= lengthChange;
|
range.length -= lengthChange;
|
||||||
// printf("invalidate %i+%i=%i\n", range.location, range.length, range.location+range.length);
|
// 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--)
|
for (i = 1; i <= new->level; i++, hn--)
|
||||||
run_fix_head(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;
|
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;
|
trailing = !next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* printf("deleted\n");
|
// printf("deleted\n");
|
||||||
[self _glyphDumpRuns];*/
|
// [self _glyphDumpRuns];
|
||||||
|
|
||||||
/* r is the last run we want to keep, and the next run is the next
|
/* 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 */
|
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])];
|
inRange: NSMakeRange(0, [_textStorage length])];
|
||||||
|
|
||||||
/* printf("at %i, max=%i, effective range (%i+%i)\n",
|
/* 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);
|
new = run_insert(context);
|
||||||
if (rng.location < ch)
|
if (rng.location < ch)
|
||||||
|
@ -1173,6 +1196,7 @@ it should still be safe. might lose opportunities to merge runs, though.
|
||||||
*actualRange = range;
|
*actualRange = range;
|
||||||
|
|
||||||
// [self _glyphDumpRuns];
|
// [self _glyphDumpRuns];
|
||||||
|
[self _sanityChecks];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1409,6 +1433,18 @@ it should still be safe. might lose opportunities to merge runs, though.
|
||||||
@implementation GSLayoutManager (layout)
|
@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
|
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange
|
||||||
isSoft: (BOOL)flag
|
isSoft: (BOOL)flag
|
||||||
actualCharacterRange: (NSRange *)actualRange
|
actualCharacterRange: (NSRange *)actualRange
|
||||||
|
@ -1857,7 +1893,7 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
return lf->used_rect;
|
return lf->used_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex
|
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex: (unsigned int)glyphIndex
|
||||||
startLocation: (NSPoint *)p
|
startLocation: (NSPoint *)p
|
||||||
{
|
{
|
||||||
int i;
|
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
|
- (void) textStorage: (NSTextStorage *)aTextStorage
|
||||||
edited: (unsigned int)mask
|
edited: (unsigned int)mask
|
||||||
range: (NSRange)range
|
range: (NSRange)range
|
||||||
|
@ -2296,23 +2337,16 @@ See [NSTextView -setTextContainer:] for more information about these calls.
|
||||||
if (!(mask & NSTextStorageEditedCharacters))
|
if (!(mask & NSTextStorageEditedCharacters))
|
||||||
lengthChange = 0;
|
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
|
[self invalidateGlyphsForCharacterRange: invalidatedRange
|
||||||
changeInLength: lengthChange
|
changeInLength: lengthChange
|
||||||
actualCharacterRange: &r];
|
actualCharacterRange: &r];
|
||||||
|
|
||||||
[self invalidateLayoutForCharacterRange: r
|
/*
|
||||||
isSoft: NO
|
See the comments above -invalidateLayoutForCharacterRange:isSoft:
|
||||||
actualCharacterRange: &r];
|
actualCharacterRange: for information on why we invalidate everything
|
||||||
r.location += r.length;
|
here.
|
||||||
r.length = [_textStorage length] - r.location;
|
*/
|
||||||
[self invalidateLayoutForCharacterRange: r
|
[self _invalidateLayoutFromContainer: 0];
|
||||||
isSoft: YES
|
|
||||||
actualCharacterRange: NULL];
|
|
||||||
|
|
||||||
[self _didInvalidateLayout];
|
[self _didInvalidateLayout];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue