git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8706 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2001-01-20 08:58:25 +00:00
parent 14014a3a62
commit 434a977c18
3 changed files with 247 additions and 210 deletions

View file

@ -1,3 +1,8 @@
2001-01-20 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSLayoutManager.m: Reorganize and tidy up glyph code
in preparation for handling gaps in the glyh stream.
Fri Jan 19 17:22:24 2001 Nicola Pero <nicola@brainstorm.co.uk> Fri Jan 19 17:22:24 2001 Nicola Pero <nicola@brainstorm.co.uk>
* GNUmakefile: Added RPM_DISABLE_RELOCATABLE and * GNUmakefile: Added RPM_DISABLE_RELOCATABLE and

View file

@ -108,7 +108,11 @@ typedef enum {
float _hyphenationFactor; float _hyphenationFactor;
NSTypesetter *_typesetter; NSTypesetter *_typesetter;
void *_glyphChunks; // Private glyph storage. void *_glyphData; // Private glyph storage.
void *_currentGlyphs;
void *_glyphGaps; // Gaps in character mapping.
unsigned _chunkIndex;
unsigned _glyphIndex;
unsigned _endCharIndex; // After last char with generated glyph. unsigned _endCharIndex; // After last char with generated glyph.
NSGlyphGenerator *_glyphGenerator; NSGlyphGenerator *_glyphGenerator;

View file

@ -35,7 +35,7 @@
#define USE_GLYPHS 0 #define USE_GLYPHS 0
#define glyphChunks ((GSIArray)_glyphChunks)
/* /*
* Glyph attributes known to the layout manager. * Glyph attributes known to the layout manager.
@ -286,12 +286,17 @@ GSDestroyChunks(GSIArray *where)
} }
} }
static void static GSGlyphChunk*
GSCreateChunks(GSIArray *where) GSCreateChunks(GSIArray *where)
{ {
GSGlyphChunk *chunk;
GSDestroyChunks(where); GSDestroyChunks(where);
*where = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t)); *where = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t));
GSIArrayInitWithZoneAndCapacity(*where, NSDefaultMallocZone(), 8); GSIArrayInitWithZoneAndCapacity(*where, NSDefaultMallocZone(), 8);
chunk = GSCreateGlyphChunk(0);
GSIArrayInsertItem(*where, (GSIArrayItem)(void*)chunk, 0);
return chunk;
} }
static inline unsigned static inline unsigned
@ -312,19 +317,9 @@ GSChunkForCharIndex(GSIArray chunks, unsigned charIndex)
charIndexSort); charIndexSort);
/* /*
* pos is the index of the next chunk *after* the one we want. * pos is the index of the next chunk *after* the one we want.
* if it is zero, we have an empty list - so we create the first chunk.
*/ */
if (pos == 0) NSCAssert(pos > 0, @"No glyph chunks present");
{
GSGlyphChunk *chunk = GSCreateGlyphChunk(0);
GSIArrayInsertItem(chunks, (GSIArrayItem)(void*)chunk, 0);
return 0;
}
else
{
pos--; pos--;
}
return pos; return pos;
} }
@ -339,154 +334,204 @@ GSChunkForGlyphIndex(GSIArray chunks, unsigned glyphIndex)
glyphIndexSort); glyphIndexSort);
/* /*
* pos is the index of the next chunk *after* the one we want. * pos is the index of the next chunk *after* the one we want.
* if it is zero, we have an empty list - so we create the first chunk.
*/ */
if (pos == 0) NSCAssert(pos > 0, @"No glyph chunks present");
{
GSGlyphChunk *chunk = GSCreateGlyphChunk(0);
GSIArrayInsertItem(chunks, (GSIArrayItem)(void*)chunk, 0);
}
else
{
pos--; pos--;
}
return pos; return pos;
} }
typedef struct {
GSIArray chunks;
GSGlyphChunk *chunk;
unsigned index;
unsigned offset;
} GlyphStepper;
static inline BOOL /*
_InitByChar(GlyphStepper *s, GSIArray chunks, unsigned charIndex) * Medium level functions for accessing and manipulating glyphs.
{
GSGlyphAttrs tmp;
s->chunks = chunks;
s->index = GSChunkForCharIndex(s->chunks, charIndex);
s->chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(s->chunks, s->index).ptr;
tmp.offset = charIndex - s->chunk->charIndex;
s->offset = GSIArrayInsertionPosition(&s->chunk->attrs,
(GSIArrayItem)tmp, offsetSort);
if (s->offset == 0)
{
[NSException raise: NSInternalInconsistencyException
format: @"error in character locations for glyphs"];
}
s->offset--;
/*
* Locate the *first* glyph for this character index.
*/ */
while (s->offset > 0 &&
(GSIArrayItemAtIndex(&s->chunk->attrs, s->offset-1).ext).offset typedef struct {
>= tmp.offset) @defs(NSLayoutManager)
} *lmDefs;
#define glyphChunks ((GSIArray)_glyphData)
#define _chunks ((GSIArray)(((lmDefs)lm)->_glyphData))
#define _chunk ((GSGlyphChunk*)(((lmDefs)lm)->_currentGlyphs))
#define _index ((lmDefs)lm)->_chunkIndex
#define _offset ((lmDefs)lm)->_glyphIndex
#define _gaps ((GSIArray)(((lmDefs)lm)->_glyphGaps))
static void _Adjust(NSLayoutManager *lm, unsigned from, int by);
static GSGlyphAttrs _Attrs(NSLayoutManager *lm);
static BOOL _Back(NSLayoutManager *lm);
static unsigned _CharIndex(NSLayoutManager *lm);
static NSGlyph _Glyph(NSLayoutManager *lm);
static unsigned _GlyphIndex(NSLayoutManager *lm);
static BOOL _JumpToChar(NSLayoutManager *lm, unsigned charIndex);
static BOOL _JumpToGlyph(NSLayoutManager *lm, unsigned glyphIndex);
static void _SetAttrs(NSLayoutManager *lm, GSGlyphAttrs a);
static void _SetGlyph(NSLayoutManager *lm, NSGlyph g);
static BOOL _Step(NSLayoutManager *lm);
static inline GSGlyphAttrs
_Attrs(NSLayoutManager *lm)
{
return GSIArrayItemAtIndex(&_chunk->attrs, _offset).ext;
}
static inline void
_SetAttrs(NSLayoutManager *lm, GSGlyphAttrs a)
{
GSIArraySetItemAtIndex(&_chunk->attrs, (GSIArrayItem)a, _offset);
}
static void
_Adjust(NSLayoutManager *lm, unsigned from, int lengthChange)
{
if (from < [((lmDefs)lm)->_textStorage length])
{ {
s->offset--; _JumpToGlyph(lm, from);
} /*
if ((GSIArrayItemAtIndex(&s->chunk->attrs, s->offset-1).ext).offset * Adjust character offsets for all glyphs in this chunk.
> tmp.offset) */
if (_offset > 0)
{ {
return NO; while (_offset < GSIArrayCount(&_chunk->glyphs))
{
GSGlyphAttrs attrs = _Attrs(lm);
attrs.offset += lengthChange;
_SetAttrs(lm, attrs);
}
}
/*
* Now adjust character offsets for remaining chunks.
*/
while (++_index < GSIArrayCount(_chunks))
{
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _index).ptr;
_chunk->charIndex += lengthChange;
}
} }
return YES;
} }
static inline BOOL static inline BOOL
_InitByGlyph(GlyphStepper *s, GSIArray chunks, unsigned glyphIndex) _Back(NSLayoutManager *lm)
{ {
s->chunks = chunks; if (_offset > 0)
s->index = GSChunkForGlyphIndex(s->chunks, glyphIndex);
s->chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(s->chunks, s->index).ptr;
s->offset = glyphIndex - s->chunk->glyphIndex;
if (s->offset < GSIArrayCount(&s->chunk->glyphs))
{ {
_offset--;
return YES;
}
else if (_index > 0)
{
_index--;
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _index).ptr;
_offset = GSIArrayCount(&_chunk->glyphs) - 1;
return YES; return YES;
} }
else else
{ {
s->offset = GSIArrayCount(&s->chunk->glyphs) - 1;
return NO; return NO;
} }
} }
static inline unsigned static inline unsigned
_CharIndex(GlyphStepper *s) _CharIndex(NSLayoutManager *lm)
{ {
return s->chunk->charIndex return _chunk->charIndex
+ (GSIArrayItemAtIndex(&s->chunk->attrs, s->offset).ext).offset; + (GSIArrayItemAtIndex(&_chunk->attrs, _offset).ext).offset;
}
static inline unsigned
_GlyphIndex(GlyphStepper *s)
{
return s->chunk->glyphIndex + s->offset;
}
static inline GSGlyphAttrs
_Attrs(GlyphStepper *s)
{
return GSIArrayItemAtIndex(&s->chunk->attrs, s->offset).ext;
}
static inline void
_SetAttrs(GlyphStepper *s, GSGlyphAttrs a)
{
GSIArraySetItemAtIndex(&s->chunk->attrs, (GSIArrayItem)a, s->offset);
} }
static inline NSGlyph static inline NSGlyph
_Glyph(GlyphStepper *s) _Glyph(NSLayoutManager *lm)
{ {
return (NSGlyph)GSIArrayItemAtIndex(&s->chunk->glyphs, s->offset).ulng; return (NSGlyph)GSIArrayItemAtIndex(&_chunk->glyphs, _offset).ulng;
}
static inline unsigned
_GlyphIndex(NSLayoutManager *lm)
{
return _chunk->glyphIndex + _offset;
}
static BOOL
_JumpToChar(NSLayoutManager *lm, unsigned charIndex)
{
GSGlyphAttrs tmp;
GSGlyphChunk *c;
unsigned i;
unsigned o;
i = GSChunkForCharIndex(_chunks, charIndex);
c = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, i).ptr;
tmp.offset = charIndex - c->charIndex;
o = GSIArrayInsertionPosition(&c->attrs, (GSIArrayItem)tmp, offsetSort);
if (o == 0)
{
return NO; // Insertion position not found.
}
o--;
/*
* Locate the *first* glyph for this character index.
*/
while (o>0 && (GSIArrayItemAtIndex(&c->attrs, o-1).ext).offset >= tmp.offset)
{
o--;
}
if ((GSIArrayItemAtIndex(&c->attrs, o).ext).offset > tmp.offset)
{
return NO;
}
_chunk = c;
_index = i;
_offset = o;
return YES;
}
static BOOL
_JumpToGlyph(NSLayoutManager *lm, unsigned glyphIndex)
{
GSGlyphChunk *c;
unsigned i;
unsigned o;
i = GSChunkForGlyphIndex(_chunks, glyphIndex);
c = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, i).ptr;
o = glyphIndex - c->glyphIndex;
if (o < GSIArrayCount(&c->glyphs))
{
_chunk = c;
_index = i;
_offset = o;
return YES;
}
else
{
return NO;
}
} }
static inline void static inline void
_SetGlyph(GlyphStepper *s, NSGlyph g) _SetGlyph(NSLayoutManager *lm, NSGlyph g)
{ {
GSIArraySetItemAtIndex(&s->chunk->glyphs, (GSIArrayItem)g, s->offset); GSIArraySetItemAtIndex(&_chunk->glyphs, (GSIArrayItem)g, _offset);
} }
static inline BOOL static inline BOOL
_Back(GlyphStepper *s) _Step(NSLayoutManager *lm)
{ {
if (s->offset > 0) if (_offset < GSIArrayCount(&_chunk->glyphs) - 1)
{ {
s->offset--; _offset++;
return YES;
}
else if (s->index > 0)
{
s->index--;
s->chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(s->chunks, s->index).ptr;
s->offset = GSIArrayCount(&s->chunk->glyphs) - 1;
return YES; return YES;
} }
else else
{ {
return NO; if (_index < GSIArrayCount(_chunks) - 1)
}
}
static inline BOOL
_Step(GlyphStepper *s)
{
if (s->offset < GSIArrayCount(&s->chunk->glyphs) - 1)
{ {
s->offset++; _index++;
return YES; _chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _index).ptr;
} _offset = 0;
else
{
if (s->index < GSIArrayCount(s->chunks) - 1)
{
s->index++;
s->chunk
= (GSGlyphChunk*)GSIArrayItemAtIndex(s->chunks, s->index).ptr;
s->offset = 0;
return YES; return YES;
} }
else else
@ -496,6 +541,8 @@ _Step(GlyphStepper *s)
} }
} }
@interface GSRunStorage : NSObject @interface GSRunStorage : NSObject
{ {
unsigned int _count; unsigned int _count;
@ -686,7 +733,9 @@ _Step(GlyphStepper *s)
*/ */
- (id) init - (id) init
{ {
[super init]; if ([super init] != nil)
{
GSIArray a;
_backgroundLayout = YES; _backgroundLayout = YES;
_delegate = nil; _delegate = nil;
@ -696,13 +745,31 @@ _Step(GlyphStepper *s)
_fragmentRuns = [GSRunStorage new]; _fragmentRuns = [GSRunStorage new];
_locationRuns = [GSRunStorage new]; _locationRuns = [GSRunStorage new];
GSCreateChunks((GSIArray*)&_glyphChunks); /*
* Initialise glyph storage and ivars to contain 'current' glyph
* location information.
*/
_currentGlyphs = GSCreateChunks((GSIArray*)&_glyphData);
_chunkIndex = 0;
_glyphIndex = 0;
/*
* Initialise storage of holes in the glyph stream.
*/
a = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t));
GSIArrayInitWithZoneAndCapacity(a, NSDefaultMallocZone(), 8);
_glyphGaps = a;
}
return self; return self;
} }
- (void) dealloc - (void) dealloc
{ {
GSDestroyChunks((GSIArray*)&_glyphChunks); GSDestroyChunks((GSIArray*)&_glyphData);
GSIArrayEmpty((GSIArray)_glyphGaps);
NSZoneFree(NSDefaultMallocZone(), _glyphGaps);
RELEASE (_textContainers); RELEASE (_textContainers);
RELEASE (_containerRuns); RELEASE (_containerRuns);
@ -870,33 +937,7 @@ _Step(GlyphStepper *s)
/* /*
* Now adjust character locations for glyphs if necessary. * Now adjust character locations for glyphs if necessary.
*/ */
if (NSMaxRange(cRange) < [_textStorage length]) _Adjust(self, NSMaxRange(cRange), lengthChange);
{
GlyphStepper s;
_InitByGlyph(&s, glyphChunks, NSMaxRange(gRange));
/*
* Adjust character offsets for all glyphs in this chunk.
*/
if (s.offset > 0)
{
while (s.offset < GSIArrayCount(&s.chunk->glyphs))
{
GSGlyphAttrs attrs = _Attrs(&s);
attrs.offset += lengthChange;
_SetAttrs(&s, attrs);
}
}
/*
* Now adjust character offsets for remaining chunks.
*/
while (++s.index < GSIArrayCount(glyphChunks))
{
s.chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(s.chunks, s.index).ptr;
s.chunk->charIndex += lengthChange;
}
}
// FIXME - should invalidate the character range ... but what does that mean? // FIXME - should invalidate the character range ... but what does that mean?
} }
@ -1344,16 +1385,14 @@ invalidatedRange.length);
isValidIndex: (BOOL*)flag isValidIndex: (BOOL*)flag
{ {
#if USE_GLYPHS #if USE_GLYPHS
GlyphStepper s;
/* /*
* If the chunk located doesn't contain the index we want, * If the chunk located doesn't contain the index we want,
* we must need to generate more glyphs from the text. * we must need to generate more glyphs from the text.
*/ */
if (_InitByGlyph(&s, glyphChunks, index) == NO) if (_JumpToGlyph(self, index) == NO)
{ {
GSGlyphChunk *chunk = s.chunk; GSGlyphChunk *chunk = (GSGlyphChunk*)_currentGlyphs;
unsigned pos = s.index; unsigned pos = _chunkIndex;
unsigned numChars; unsigned numChars;
unsigned numGlyphs; unsigned numGlyphs;
NSString *string; NSString *string;
@ -1383,10 +1422,10 @@ invalidatedRange.length);
} }
} }
} }
if (_InitByGlyph(&s, glyphChunks, index) == YES) if (_JumpToGlyph(self, index) == YES)
{ {
*flag = YES; *flag = YES;
return _Glyph(&s); return _Glyph(self);
} }
else else
{ {
@ -1404,14 +1443,12 @@ invalidatedRange.length);
- (void) replaceGlyphAtIndex: (unsigned)index - (void) replaceGlyphAtIndex: (unsigned)index
withGlyph: (NSGlyph)newGlyph withGlyph: (NSGlyph)newGlyph
{ {
GlyphStepper s; if (_JumpToGlyph(self, index) == NO)
if (_InitByGlyph(&s, glyphChunks, index) == NO)
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"glyph index out of range"]; format: @"glyph index out of range"];
} }
_SetGlyph(&s, newGlyph); _SetGlyph(self, newGlyph);
} }
// This causes glyph generation similarly to asking for a single // This causes glyph generation similarly to asking for a single
@ -1432,25 +1469,23 @@ invalidatedRange.length);
if (toFetch > 0) if (toFetch > 0)
{ {
GlyphStepper s;
/* /*
* Force generation of glyphs to fill range. * Force generation of glyphs to fill range.
*/ */
[self glyphAtIndex: NSMaxRange(glyphRange)-1]; [self glyphAtIndex: NSMaxRange(glyphRange)-1];
_InitByGlyph(&s, glyphChunks, glyphRange.location); _JumpToGlyph(self, glyphRange.location);
/* /*
* Now return glyphs, excluding those 'not shown' * Now return glyphs, excluding those 'not shown'
*/ */
while (toFetch-- > 0) while (toFetch-- > 0)
{ {
if (_Attrs(&s).isNotShown == 0) if (_Attrs(self).isNotShown == 0)
{ {
glyphArray[packed++] = _Glyph(&s); glyphArray[packed++] = _Glyph(self);
} }
_Step(&s); // Move to next glyph. _Step(self); // Move to next glyph.
} }
} }
glyphArray[packed] = 0; glyphArray[packed] = 0;
@ -1575,22 +1610,21 @@ invalidatedRange.length);
- (void) setCharacterIndex: (unsigned)charIndex - (void) setCharacterIndex: (unsigned)charIndex
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
GlyphStepper s;
GSGlyphAttrs attrs; GSGlyphAttrs attrs;
int diff; int diff;
if (_InitByGlyph(&s, glyphChunks, glyphIndex) == NO) if (_JumpToGlyph(self, glyphIndex) == NO)
{ {
[self glyphAtIndex: glyphIndex]; [self glyphAtIndex: glyphIndex];
_InitByGlyph(&s, glyphChunks, glyphIndex); _JumpToGlyph(self, glyphIndex);
} }
diff = charIndex - _CharIndex(&s); diff = charIndex - _CharIndex(self);
if (diff == 0) if (diff == 0)
{ {
return; // Already set - nothing to do. return; // Already set - nothing to do.
} }
if (_Back(&s) == NO) if (_Back(self) == NO)
{ {
if (charIndex != 0) if (charIndex != 0)
{ {
@ -1599,42 +1633,42 @@ invalidatedRange.length);
} }
return; return;
} }
if (_CharIndex(&s) > charIndex) if (_CharIndex(self) > charIndex)
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"set index lower than preceeding glyph"]; format: @"set index lower than preceeding glyph"];
} }
_Step(&s); _Step(self);
if (_Step(&s) == YES && charIndex > _CharIndex(&s)) if (_Step(self) == YES && charIndex > _CharIndex(self))
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"set index higher than following glyph"]; format: @"set index higher than following glyph"];
} }
_Back(&s); _Back(self);
/* /*
* If this is the start of a chunk, we adjust the character position * If this is the start of a chunk, we adjust the character position
* for the chunk as a whole, then fix each glyph in turn. Otherwise * for the chunk as a whole, then fix each glyph in turn. Otherwise
* we simply adjust the glyph concerned. * we simply adjust the glyph concerned.
*/ */
if (s.offset == 0) if (_glyphIndex == 0)
{ {
GSGlyphChunk *chunk = s.chunk; GSGlyphChunk *chunk = (GSGlyphChunk*)_currentGlyphs;
diff = charIndex - _CharIndex(&s); diff = charIndex - _CharIndex(self);
s.chunk->charIndex += diff; chunk->charIndex += diff;
while (_Step(&s) == YES && s.chunk == chunk) while (_Step(self) == YES && (GSGlyphChunk*)_currentGlyphs == chunk)
{ {
attrs = _Attrs(&s); attrs = _Attrs(self);
attrs.offset += diff; attrs.offset += diff;
_SetAttrs(&s, attrs); _SetAttrs(self, attrs);
} }
} }
else else
{ {
attrs = _Attrs(&s); attrs = _Attrs(self);
attrs.offset += diff; attrs.offset += diff;
_SetAttrs(&s, attrs); _SetAttrs(self, attrs);
} }
} }
@ -1644,14 +1678,12 @@ invalidatedRange.length);
- (unsigned) characterIndexForGlyphAtIndex: (unsigned)glyphIndex - (unsigned) characterIndexForGlyphAtIndex: (unsigned)glyphIndex
{ {
#if USE_GLYPHS #if USE_GLYPHS
GlyphStepper s; if (_JumpToGlyph(self, glyphIndex) == NO)
if (_InitByGlyph(&s, glyphChunks, glyphIndex) == NO)
{ {
[self glyphAtIndex: glyphIndex]; [self glyphAtIndex: glyphIndex];
_InitByGlyph(&s, glyphChunks, glyphIndex); _JumpToGlyph(self, glyphIndex);
} }
return _CharIndex(&s); return _CharIndex(self);
#else #else
return glyphIndex; return glyphIndex;
#endif #endif
@ -1670,7 +1702,6 @@ invalidatedRange.length);
actualGlyphRange: (NSRange*)actualGlyphRange actualGlyphRange: (NSRange*)actualGlyphRange
{ {
#if USE_GLYPHS #if USE_GLYPHS
GlyphStepper s;
unsigned pos; unsigned pos;
NSRange cRange; NSRange cRange;
NSRange gRange = glyphRange; NSRange gRange = glyphRange;
@ -1681,9 +1712,9 @@ invalidatedRange.length);
* Locate the first glyph and step backwards to the earliest glyph with * Locate the first glyph and step backwards to the earliest glyph with
* the same character index. * the same character index.
*/ */
_InitByGlyph(&s, glyphChunks, glyphRange.location); _JumpToGlyph(self, glyphRange.location);
cRange.location = _CharIndex(&s); cRange.location = _CharIndex(self);
while (_Back(&s) == YES && _CharIndex(&s) == cRange.location) while (_Back(self) == YES && _CharIndex(self) == cRange.location)
{ {
gRange.location--; gRange.location--;
gRange.length++; gRange.length++;
@ -1706,16 +1737,16 @@ invalidatedRange.length);
/* /*
* Locate the glyph immediately beyond the range. * Locate the glyph immediately beyond the range.
*/ */
if (_InitByGlyph(&s, glyphChunks, NSMaxRange(glyphRange)) == NO) if (_JumpToGlyph(self, NSMaxRange(glyphRange)) == NO)
{ {
pos = _endCharIndex - 1; pos = _endCharIndex - 1;
gRange.length = _GlyphIndex(&s) - gRange.location; gRange.length = _GlyphIndex(self) - gRange.location;
} }
else else
{ {
pos = _CharIndex(&s); pos = _CharIndex(self);
gRange.length = _GlyphIndex(&s) - gRange.location; gRange.length = _GlyphIndex(self) - gRange.location;
while (_Back(&s) == YES && _CharIndex(&s) == pos) while (_Back(self) == YES && _CharIndex(self) == pos)
{ {
gRange.length--; gRange.length--;
} }
@ -1748,7 +1779,6 @@ invalidatedRange.length);
actualCharacterRange: (NSRange*)actualCharRange actualCharacterRange: (NSRange*)actualCharRange
{ {
#if USE_GLYPHS #if USE_GLYPHS
GlyphStepper s;
unsigned pos; unsigned pos;
NSRange cRange = charRange; NSRange cRange = charRange;
NSRange gRange; NSRange gRange;
@ -1759,13 +1789,13 @@ invalidatedRange.length);
/* /*
* Locate the first glyph corresponding to the start character. * Locate the first glyph corresponding to the start character.
*/ */
_InitByChar(&s, glyphChunks, charRange.location); _JumpToChar(self, charRange.location);
gRange.location = _GlyphIndex(&s); gRange.location = _GlyphIndex(self);
/* /*
* Adjust start character if necessary. * Adjust start character if necessary.
*/ */
pos = _CharIndex(&s); pos = _CharIndex(self);
if (pos < cRange.location) if (pos < cRange.location)
{ {
cRange.length += (cRange.location - pos); cRange.length += (cRange.location - pos);
@ -1792,10 +1822,10 @@ invalidatedRange.length);
* Locate the glyph immediately beyond the range, * Locate the glyph immediately beyond the range,
* and calculate the length of the range from that. * and calculate the length of the range from that.
*/ */
_InitByChar(&s, glyphChunks, NSMaxRange(charRange)); _JumpToChar(self, NSMaxRange(charRange));
pos = _GlyphIndex(&s); pos = _GlyphIndex(self);
gRange.length = pos - gRange.location; gRange.length = pos - gRange.location;
pos = _CharIndex(&s); pos = _CharIndex(self);
cRange.length = pos - cRange.location; cRange.length = pos - cRange.location;
} }
if (actualCharRange != 0) if (actualCharRange != 0)
@ -1837,15 +1867,14 @@ invalidatedRange.length);
value: (int)anInt value: (int)anInt
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
GlyphStepper s;
GSGlyphAttrs attrs; GSGlyphAttrs attrs;
if (_InitByGlyph(&s, glyphChunks, glyphIndex) == NO) if (_JumpToGlyph(self, glyphIndex) == NO)
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"glyph index out of range"]; format: @"glyph index out of range"];
} }
attrs = _Attrs(&s); attrs = _Attrs(self);
if (attribute == GSGlyphDrawsOutsideLineFragment) if (attribute == GSGlyphDrawsOutsideLineFragment)
{ {
if (anInt == 0) if (anInt == 0)
@ -1876,7 +1905,7 @@ invalidatedRange.length);
{ {
attrs.inscription = anInt; attrs.inscription = anInt;
} }
_SetAttrs(&s, attrs); _SetAttrs(self, attrs);
} }
// This returns the value for the given glyph attribute at the glyph // This returns the value for the given glyph attribute at the glyph
@ -1887,15 +1916,14 @@ invalidatedRange.length);
- (int) intAttribute: (int)attribute - (int) intAttribute: (int)attribute
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
GlyphStepper s;
GSGlyphAttrs attrs; GSGlyphAttrs attrs;
if (_InitByGlyph(&s, glyphChunks, glyphIndex) == NO) if (_JumpToGlyph(self, glyphIndex) == NO)
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"glyph index out of range"]; format: @"glyph index out of range"];
} }
attrs = _Attrs(&s); attrs = _Attrs(self);
if (attribute == GSGlyphDrawsOutsideLineFragment) if (attribute == GSGlyphDrawsOutsideLineFragment)
{ {