mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 20:01:11 +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
1ba6d8c940
commit
bdc3373174
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>
|
||||
|
||||
* 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
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue