mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 20:01:11 +00:00
More layout fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@12608 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9a2a55ecee
commit
d95eb2ac84
3 changed files with 270 additions and 124 deletions
|
@ -105,13 +105,12 @@ typedef enum {
|
|||
float _hyphenationFactor;
|
||||
NSTypesetter *_typesetter;
|
||||
|
||||
void *_glyphData; // Private glyph storage.
|
||||
void *_glyphData; // Private glyph storage.
|
||||
void *_currentGlyphs; // Current chunk pointer.
|
||||
unsigned _currentGlyph; // Current glyph index.
|
||||
void *_glyphGaps; // Gaps in character mapping.
|
||||
unsigned _glyphIndex; // Current glyph index.
|
||||
void *_glyphGaps; // Gaps in character mapping.
|
||||
unsigned _chunkIndex; // Current chunk in glyph stream.
|
||||
unsigned _glyphIndex; // Current glyph in chunk.
|
||||
unsigned _numberOfGlyphs; // After last generated glyph.
|
||||
unsigned _glyphOffset; // Current glyph in chunk.
|
||||
|
||||
NSGlyphGenerator *_glyphGenerator;
|
||||
|
||||
|
|
|
@ -36,9 +36,17 @@
|
|||
#include <Foundation/NSException.h>
|
||||
|
||||
#define USE_GLYPHS 0
|
||||
#define ALL_CHECKS 0
|
||||
|
||||
#define BOTH (NSTextStorageEditedCharacters | NSTextStorageEditedAttributes)
|
||||
|
||||
#if ALL_CHECKS
|
||||
static void missmatch(SEL s)
|
||||
{
|
||||
NSLog(@"Missmatch in %@", NSStringFromSelector(s));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Glyph attributes known to the layout manager.
|
||||
*/
|
||||
|
@ -209,8 +217,8 @@ GSCreateGlyphChunk(unsigned glyphIndex, unsigned charIndex)
|
|||
chunk = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSGlyphChunk));
|
||||
chunk->charIndex = charIndex;
|
||||
chunk->glyphIndex = glyphIndex;
|
||||
GSIArrayInitWithZoneAndCapacity(&chunk->glyphs, NSDefaultMallocZone(), 128);
|
||||
GSIArrayInitWithZoneAndCapacity(&chunk->attrs, NSDefaultMallocZone(), 128);
|
||||
GSIArrayInitWithZoneAndCapacity(&chunk->glyphs, NSDefaultMallocZone(), 8);
|
||||
GSIArrayInitWithZoneAndCapacity(&chunk->attrs, NSDefaultMallocZone(), 8);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
@ -277,9 +285,9 @@ typedef struct {
|
|||
|
||||
#define _chunks ((GSIArray)(((lmDefs)lm)->_glyphData))
|
||||
#define _chunk ((GSGlyphChunk*)(((lmDefs)lm)->_currentGlyphs))
|
||||
#define _current (((lmDefs)lm)->_currentGlyph)
|
||||
#define _index (((lmDefs)lm)->_chunkIndex)
|
||||
#define _offset (((lmDefs)lm)->_glyphIndex)
|
||||
#define _gindex (((lmDefs)lm)->_glyphIndex)
|
||||
#define _cindex (((lmDefs)lm)->_chunkIndex)
|
||||
#define _offset (((lmDefs)lm)->_glyphOffset)
|
||||
#define _gaps ((GSIArray)(((lmDefs)lm)->_glyphGaps))
|
||||
|
||||
|
||||
|
@ -307,15 +315,15 @@ _Back(NSLayoutManager *lm)
|
|||
if (_offset > 0)
|
||||
{
|
||||
_offset--;
|
||||
_current--;
|
||||
_gindex--;
|
||||
return YES;
|
||||
}
|
||||
else if (_index > 0)
|
||||
else if (_cindex > 0)
|
||||
{
|
||||
_index--;
|
||||
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _index).ptr;
|
||||
_cindex--;
|
||||
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _cindex).ptr;
|
||||
_offset = GSIArrayCount(&_chunk->glyphs) - 1;
|
||||
_current--;
|
||||
_gindex--;
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
|
@ -334,17 +342,17 @@ _Step(NSLayoutManager *lm)
|
|||
if (_offset < GSIArrayCount(&_chunk->glyphs) - 1)
|
||||
{
|
||||
_offset++;
|
||||
_current++;
|
||||
_gindex++;
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_index < GSIArrayCount(_chunks) - 1)
|
||||
if (_cindex < GSIArrayCount(_chunks) - 1)
|
||||
{
|
||||
_index++;
|
||||
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _index).ptr;
|
||||
_cindex++;
|
||||
_chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(_chunks, _cindex).ptr;
|
||||
_offset = 0;
|
||||
_current++;
|
||||
_gindex++;
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
|
@ -364,7 +372,7 @@ _Adjust(NSLayoutManager *lm, unsigned from, int lengthChange)
|
|||
if (_JumpToGlyph(lm, from) == YES)
|
||||
{
|
||||
GSGlyphChunk *chunk = _chunk;
|
||||
unsigned index = _index;
|
||||
unsigned index = _cindex;
|
||||
unsigned offset = _offset;
|
||||
|
||||
/*
|
||||
|
@ -511,7 +519,7 @@ _JumpToChar(NSLayoutManager *lm, unsigned charIndex)
|
|||
* character index we were asked for. If it doesn't we have probably
|
||||
* failed to find a glyph matching the character.
|
||||
*/
|
||||
co = (GSIArrayItemAtIndex(&c->attrs, o-1).ext).offset;
|
||||
co = (GSIArrayItemAtIndex(&c->attrs, o).ext).offset;
|
||||
if (co + c->charIndex != charIndex)
|
||||
{
|
||||
if ([((lmDefs)lm)->_textStorage length] > charIndex)
|
||||
|
@ -526,6 +534,10 @@ _JumpToChar(NSLayoutManager *lm, unsigned charIndex)
|
|||
* The requested character is part of a composed character
|
||||
* sequence whose first character maps on to the glyph we found.
|
||||
*/
|
||||
_chunk = c;
|
||||
_cindex = i;
|
||||
_offset = o;
|
||||
_gindex = c->glyphIndex + o;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -540,9 +552,9 @@ _JumpToChar(NSLayoutManager *lm, unsigned charIndex)
|
|||
o--;
|
||||
}
|
||||
_chunk = c;
|
||||
_index = i;
|
||||
_cindex = i;
|
||||
_offset = o;
|
||||
_current = c->glyphIndex + o;
|
||||
_gindex = c->glyphIndex + o;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -565,9 +577,9 @@ _JumpToGlyph(NSLayoutManager *lm, unsigned glyphIndex)
|
|||
if (GSIArrayCount(&c->glyphs) > 0)
|
||||
{
|
||||
_chunk = c;
|
||||
_index = 0;
|
||||
_cindex = 0;
|
||||
_offset = 0;
|
||||
_current = 0;
|
||||
_gindex = 0;
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
|
@ -579,9 +591,9 @@ _JumpToGlyph(NSLayoutManager *lm, unsigned glyphIndex)
|
|||
if (o < GSIArrayCount(&c->glyphs))
|
||||
{
|
||||
_chunk = c;
|
||||
_index = i;
|
||||
_cindex = i;
|
||||
_offset = o;
|
||||
_current = c->glyphIndex + o;
|
||||
_gindex = glyphIndex;
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
|
@ -659,26 +671,23 @@ _Sane(NSLayoutManager *lm)
|
|||
static void
|
||||
_GLog(NSLayoutManager *lm, SEL _cmd)
|
||||
{
|
||||
unsigned lastGlyph = 0;
|
||||
unsigned lastChar = 0;
|
||||
#if ALL_CHECKS
|
||||
unsigned pos;
|
||||
|
||||
/*
|
||||
* Check gaps.
|
||||
*/
|
||||
fprintf(stderr, "%s, %x\ngaps (%u) - ",
|
||||
sel_get_name(_cmd), (unsigned)lm, GSIArrayCount(_gaps));
|
||||
_cmd ? sel_get_name(_cmd) : "", (unsigned)lm, GSIArrayCount(_gaps));
|
||||
for (pos = 0; pos < GSIArrayCount(_gaps); pos++)
|
||||
{
|
||||
unsigned val = GSIArrayItemAtIndex(_gaps, pos).ulng;
|
||||
|
||||
fprintf(stderr, " %u", val);
|
||||
lastGlyph = val;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "chunks (%u) -\n", GSIArrayCount(_chunks));
|
||||
lastGlyph = 0;
|
||||
for (pos = 0; pos < GSIArrayCount(_chunks); pos++)
|
||||
{
|
||||
GSGlyphChunk *chunk;
|
||||
|
@ -699,13 +708,12 @@ _GLog(NSLayoutManager *lm, SEL _cmd)
|
|||
fprintf(stderr, " %4d %4d %c",
|
||||
chunk->glyphIndex + i,
|
||||
chunk->charIndex + a.offset,
|
||||
(char)GSIArrayItemAtIndex(&_chunk->glyphs, _offset + i).ulng);
|
||||
lastChar = chunk->charIndex + a.offset;
|
||||
(char)GSIArrayItemAtIndex(&chunk->glyphs, i).ulng);
|
||||
}
|
||||
lastGlyph = chunk->glyphIndex + count - 1;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
|
@ -765,12 +773,13 @@ _GLog(NSLayoutManager *lm, SEL _cmd)
|
|||
* Initialise glyph storage and ivars to contain 'current' glyph
|
||||
* location information.
|
||||
*/
|
||||
_glyphData = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t));
|
||||
GSIArrayInitWithZoneAndCapacity(glyphChunks, NSDefaultMallocZone(), 8);
|
||||
a = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIArray_t));
|
||||
GSIArrayInitWithZoneAndCapacity(a, NSDefaultMallocZone(), 8);
|
||||
_glyphData = a;
|
||||
_currentGlyphs = GSCreateGlyphChunk(0, 0);
|
||||
GSIArrayInsertItem(glyphChunks, (GSIArrayItem)_currentGlyphs, 0);
|
||||
_chunkIndex = 0;
|
||||
_glyphIndex = 0;
|
||||
_glyphOffset = 0;
|
||||
|
||||
/*
|
||||
* Initialise storage of gaps in the glyph stream.
|
||||
|
@ -991,9 +1000,18 @@ _GLog(NSLayoutManager *lm, SEL _cmd)
|
|||
NSRange cRange;
|
||||
NSRange gRange;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (actualRange != 0)
|
||||
{
|
||||
*actualRange = cRange;
|
||||
}
|
||||
if (aRange.length == 0)
|
||||
{
|
||||
return;
|
||||
return; // Empty ... nothing to do.
|
||||
}
|
||||
if (aRange.location >= _CharEnd(self))
|
||||
{
|
||||
return; // No glyphs generated for that character index.
|
||||
}
|
||||
|
||||
gRange = [self glyphRangeForCharacterRange: aRange
|
||||
|
@ -1016,9 +1034,10 @@ _GLog(NSLayoutManager *lm, SEL _cmd)
|
|||
|
||||
/*
|
||||
* Unless the 'lengthChange' accounts for the entire character range
|
||||
* that we deleted glyphs for, we must note the presence of a gap.
|
||||
* or the deleted glyphs were at the end of the glyph stream, we must
|
||||
* note the presence of a gap.
|
||||
*/
|
||||
if (cRange.length + lengthChange > 0)
|
||||
if (cRange.length + lengthChange > -1 && gRange.location < _GlyphEnd(self))
|
||||
{
|
||||
unsigned count = GSIArrayCount((GSIArray)_glyphGaps);
|
||||
|
||||
|
@ -1385,9 +1404,10 @@ _GLog(self,_cmd);
|
|||
/*
|
||||
* Shall we add to the chunk or is it big enough already?
|
||||
*/
|
||||
if (gCount > 100 && gCount == GSIArrayCapacity(&chunk->glyphs))
|
||||
if (gCount > 4 && gCount == GSIArrayCapacity(&chunk->glyphs))
|
||||
{
|
||||
GSGlyphChunk *newChunk = 0;
|
||||
unsigned from;
|
||||
unsigned pos;
|
||||
unsigned splitAt = gCount/2;
|
||||
unsigned splitChar;
|
||||
|
@ -1420,7 +1440,8 @@ _GLog(self,_cmd);
|
|||
GSIArrayInsertItem(glyphChunks, (GSIArrayItem)(void*)newChunk,
|
||||
chunkIndex+1);
|
||||
pos = 0;
|
||||
while (GSIArrayCount(&chunk->glyphs) > splitAt)
|
||||
from = splitAt;
|
||||
while (from < GSIArrayCount(&chunk->glyphs))
|
||||
{
|
||||
GSGlyphAttrs attrs;
|
||||
NSGlyph glyph;
|
||||
|
@ -1429,8 +1450,7 @@ _GLog(self,_cmd);
|
|||
* Remove attributes from old chunk and add to new.
|
||||
* Adjust offset for character index of new chunk.
|
||||
*/
|
||||
attrs = GSIArrayItemAtIndex(&chunk->attrs, splitAt).ext;
|
||||
GSIArrayRemoveItemAtIndex(&chunk->attrs, splitAt);
|
||||
attrs = GSIArrayItemAtIndex(&chunk->attrs, from).ext;
|
||||
attrs.offset -= splitChar;
|
||||
GSIArrayInsertItem(&newChunk->attrs,
|
||||
(GSIArrayItem)attrs, pos);
|
||||
|
@ -1438,13 +1458,15 @@ _GLog(self,_cmd);
|
|||
/*
|
||||
* Remove glyph from old chunk and add to new.
|
||||
*/
|
||||
glyph = GSIArrayItemAtIndex(&chunk->glyphs, splitAt).ulng;
|
||||
GSIArrayRemoveItemAtIndex(&chunk->glyphs, splitAt);
|
||||
glyph = GSIArrayItemAtIndex(&chunk->glyphs, from).ulng;
|
||||
GSIArrayInsertItem(&newChunk->glyphs,
|
||||
(GSIArrayItem)glyph, pos);
|
||||
|
||||
from++;
|
||||
pos++;
|
||||
}
|
||||
GSIArrayRemoveItemsFromIndex(&chunk->glyphs, splitAt);
|
||||
GSIArrayRemoveItemsFromIndex(&chunk->attrs, splitAt);
|
||||
/*
|
||||
* And set up so we point at the correct half of the split chunk.
|
||||
*/
|
||||
|
@ -1452,9 +1474,9 @@ _GLog(self,_cmd);
|
|||
{
|
||||
chunkIndex++;
|
||||
chunk = newChunk;
|
||||
gCount = GSIArrayCount(&chunk->glyphs);
|
||||
gOffset = glyphIndex - chunk->glyphIndex;
|
||||
}
|
||||
gCount = GSIArrayCount(&chunk->glyphs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1548,6 +1570,7 @@ _Sane(self);
|
|||
isValidIndex: (BOOL*)flag
|
||||
{
|
||||
#if USE_GLYPHS
|
||||
NSGlyph glyph;
|
||||
NSString *string = nil;
|
||||
unsigned textLength = [_textStorage length];
|
||||
|
||||
|
@ -1573,7 +1596,7 @@ _GLog(self,_cmd);
|
|||
{
|
||||
/*
|
||||
* Locate the glyph that preceeds the gap, and start with the
|
||||
* a character one beyond the one that generated the glyph.
|
||||
* a character one beyond the one that generated that glyph.
|
||||
* This guarantees that we won't try to re-generate the
|
||||
* preceeding glyph.
|
||||
* FIXME ... probably too simplistic an algorithm if we have
|
||||
|
@ -1608,9 +1631,13 @@ _GLog(self,_cmd);
|
|||
}
|
||||
/*
|
||||
* We have generated glyphs upto or beyond the gap, so we
|
||||
* can remove this gap entry.
|
||||
* can remove this gap and any others we have gone past.
|
||||
*/
|
||||
GSIArrayRemoveItemAtIndex((GSIArray)_glyphGaps, 0);
|
||||
while (GSIArrayCount((GSIArray)_glyphGaps) > 0
|
||||
&& GSIArrayItemAtIndex((GSIArray)_glyphGaps, 0).ulng < gap)
|
||||
{
|
||||
GSIArrayRemoveItemAtIndex((GSIArray)_glyphGaps, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1640,13 +1667,31 @@ _Sane(self);
|
|||
if (_JumpToGlyph(self, index) == YES)
|
||||
{
|
||||
*flag = YES;
|
||||
return _Glyph(self);
|
||||
glyph = _Glyph(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
*flag = NO;
|
||||
return NSNullGlyph;
|
||||
glyph = NSNullGlyph;
|
||||
}
|
||||
#if ALL_CHECKS
|
||||
if (index >= [_textStorage length])
|
||||
{
|
||||
if (glyph != NSNullGlyph)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
*flag = NO;
|
||||
glyph = NSNullGlyph;
|
||||
}
|
||||
}
|
||||
else if (glyph != (NSGlyph)[[_textStorage string] characterAtIndex: index])
|
||||
{
|
||||
missmatch(_cmd);
|
||||
*flag = YES;
|
||||
glyph = (NSGlyph)[[_textStorage string] characterAtIndex: index];
|
||||
}
|
||||
#endif
|
||||
return glyph;
|
||||
#else
|
||||
return (NSGlyph)[[_textStorage string] characterAtIndex: index];
|
||||
#endif
|
||||
|
@ -1660,12 +1705,14 @@ _Sane(self);
|
|||
- (void) replaceGlyphAtIndex: (unsigned)index
|
||||
withGlyph: (NSGlyph)newGlyph
|
||||
{
|
||||
_GLog(self,_cmd);
|
||||
if (_JumpToGlyph(self, index) == NO)
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
format: @"glyph index out of range"];
|
||||
}
|
||||
_SetGlyph(self, newGlyph);
|
||||
_GLog(self,_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1686,6 +1733,7 @@ _Sane(self);
|
|||
unsigned packed = 0;
|
||||
unsigned toFetch = glyphRange.length;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (toFetch > 0)
|
||||
{
|
||||
/*
|
||||
|
@ -1708,6 +1756,7 @@ _Sane(self);
|
|||
}
|
||||
}
|
||||
glyphArray[packed] = 0;
|
||||
_GLog(self,_cmd);
|
||||
return packed;
|
||||
}
|
||||
|
||||
|
@ -1724,6 +1773,7 @@ _Sane(self);
|
|||
unsigned pos;
|
||||
GSGlyphChunk *chunk;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (aRange.length == 0)
|
||||
{
|
||||
return; // Nothing to delete.
|
||||
|
@ -1781,10 +1831,10 @@ _Sane(self);
|
|||
GSIArrayRemoveItemsFromIndex(&chunk->glyphs, offset);
|
||||
GSIArrayRemoveItemsFromIndex(&chunk->attrs, offset);
|
||||
}
|
||||
chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(glyphChunks, chunkEnd).ptr;
|
||||
}
|
||||
|
||||
chunk = (GSGlyphChunk*)GSIArrayItemAtIndex(glyphChunks, chunkEnd).ptr;
|
||||
offset = NSMaxRange(aRange)-1 - chunk->glyphIndex;
|
||||
offset = NSMaxRange(aRange) - chunk->glyphIndex;
|
||||
if (chunk->glyphIndex < aRange.location)
|
||||
{
|
||||
from = aRange.location - chunk->glyphIndex;
|
||||
|
@ -1860,20 +1910,26 @@ _Sane(self);
|
|||
*/
|
||||
- (unsigned) numberOfGlyphs
|
||||
{
|
||||
unsigned result;
|
||||
#if USE_GLYPHS
|
||||
if (GSIArrayCount((GSIArray)_glyphGaps) > 0)
|
||||
{
|
||||
BOOL valid;
|
||||
BOOL valid;
|
||||
|
||||
/*
|
||||
* Force generation of all glyphs.
|
||||
*/
|
||||
[self glyphAtIndex: 0x7fffffff isValidIndex: &valid];
|
||||
/*
|
||||
* Force generation of all glyphs.
|
||||
*/
|
||||
[self glyphAtIndex: 0x7fffffff isValidIndex: &valid];
|
||||
result = _GlyphEnd(self);
|
||||
#if ALL_CHECKS
|
||||
if (result != [_textStorage length])
|
||||
{
|
||||
missmatch(_cmd);
|
||||
result = [_textStorage length];
|
||||
}
|
||||
return _GlyphEnd(self);
|
||||
#else
|
||||
return [_textStorage length];
|
||||
#endif
|
||||
#else
|
||||
result = [_textStorage length];
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1886,6 +1942,7 @@ _Sane(self);
|
|||
GSGlyphAttrs attrs;
|
||||
int diff;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (_JumpToGlyph(self, glyphIndex) == NO)
|
||||
{
|
||||
[self glyphAtIndex: glyphIndex];
|
||||
|
@ -1924,7 +1981,7 @@ _Sane(self);
|
|||
* for the chunk as a whole, then fix each glyph in turn. Otherwise
|
||||
* we simply adjust the glyph concerned.
|
||||
*/
|
||||
if (_glyphIndex == 0)
|
||||
if (_glyphOffset == 0)
|
||||
{
|
||||
GSGlyphChunk *chunk = (GSGlyphChunk*)_currentGlyphs;
|
||||
|
||||
|
@ -1954,13 +2011,21 @@ _Sane(self);
|
|||
*/
|
||||
- (unsigned) characterIndexForGlyphAtIndex: (unsigned)glyphIndex
|
||||
{
|
||||
unsigned result;
|
||||
|
||||
#if USE_GLYPHS
|
||||
_GLog(self,_cmd);
|
||||
if (_JumpToGlyph(self, glyphIndex) == NO)
|
||||
{
|
||||
BOOL exists;
|
||||
|
||||
[self glyphAtIndex: glyphIndex isValidIndex: &exists];
|
||||
if (exists == NO)
|
||||
if (exists == YES)
|
||||
{
|
||||
_JumpToGlyph(self, glyphIndex);
|
||||
result = _CharIndex(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* As a special case, the glyph index just beyond the end of
|
||||
|
@ -1969,17 +2034,31 @@ _Sane(self);
|
|||
*/
|
||||
if (glyphIndex == _GlyphEnd(self))
|
||||
{
|
||||
return [_textStorage length];
|
||||
result = [_textStorage length];
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
format: @"glyph index out of range"];
|
||||
}
|
||||
[NSException raise: NSRangeException
|
||||
format: @"glyph index out of range"];
|
||||
}
|
||||
_JumpToGlyph(self, glyphIndex);
|
||||
}
|
||||
return _CharIndex(self);
|
||||
#else
|
||||
return glyphIndex;
|
||||
else
|
||||
{
|
||||
result = _CharIndex(self);
|
||||
}
|
||||
#if ALL_CHECKS
|
||||
if (result != glyphIndex)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
result = glyphIndex;
|
||||
}
|
||||
#endif
|
||||
_GLog(self,_cmd);
|
||||
#else
|
||||
result = glyphIndex;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1996,12 +2075,13 @@ _Sane(self);
|
|||
- (NSRange) characterRangeForGlyphRange: (NSRange)glyphRange
|
||||
actualGlyphRange: (NSRange*)actualGlyphRange
|
||||
{
|
||||
#if USE_GLYPHS
|
||||
NSRange cRange;
|
||||
NSRange gRange = glyphRange;
|
||||
#if USE_GLYPHS
|
||||
unsigned cEnd;
|
||||
BOOL exists;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
/*
|
||||
* Force generation of glyphs to fill gaps.
|
||||
*/
|
||||
|
@ -2039,17 +2119,28 @@ _Sane(self);
|
|||
gRange.length++;
|
||||
}
|
||||
|
||||
#if ALL_CHECKS
|
||||
if (NSEqualRanges(cRange, glyphRange) == NO)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
cRange = glyphRange;
|
||||
}
|
||||
if (NSEqualRanges(gRange, glyphRange) == NO)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
gRange = glyphRange;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// Currently gyphIndex is the same as character index
|
||||
gRange = glyphRange;
|
||||
cRange = glyphRange;
|
||||
#endif
|
||||
if (actualGlyphRange != 0)
|
||||
{
|
||||
*actualGlyphRange = gRange;
|
||||
}
|
||||
return cRange;
|
||||
#else
|
||||
// Currently gyphIndex is the same as character index
|
||||
if (actualGlyphRange != NULL)
|
||||
*actualGlyphRange = glyphRange;
|
||||
return glyphRange;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2067,78 +2158,131 @@ _Sane(self);
|
|||
- (NSRange) glyphRangeForCharacterRange: (NSRange)charRange
|
||||
actualCharacterRange: (NSRange*)actualCharRange
|
||||
{
|
||||
NSRange gRange;
|
||||
#if USE_GLYPHS
|
||||
unsigned pos;
|
||||
NSRange cRange = charRange;
|
||||
NSRange gRange;
|
||||
unsigned numGlyphs;
|
||||
BOOL valid;
|
||||
|
||||
numGlyphs = [self numberOfGlyphs]; // Force generation of glyphs.
|
||||
/*
|
||||
* If the range we have been given begins or ends with a composed
|
||||
* character sequence, we must extend it to encompass the entire
|
||||
* sequence. We store the actual range in cRange.
|
||||
*/
|
||||
if (charRange.length > 0)
|
||||
{
|
||||
NSString *s = [_textStorage string];
|
||||
NSRange r;
|
||||
|
||||
r = [s rangeOfComposedCharacterSequenceAtIndex: cRange.location];
|
||||
if (r.length > 0)
|
||||
{
|
||||
cRange.length += (cRange.location - r.location);
|
||||
cRange.location = r.location;
|
||||
}
|
||||
if (NSMaxRange(charRange) > NSMaxRange(r))
|
||||
{
|
||||
pos = NSMaxRange(charrange) - 1;
|
||||
r = [s rangeOfComposedCharacterSequenceAtIndex: pos];
|
||||
if (r.length > 0)
|
||||
{
|
||||
cRange.length += r.length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_GLog(self,_cmd);
|
||||
// Force generation of glyphs.
|
||||
[self glyphAtIndex: NSMaxRange(cRange) - 1 isValidIndex: &valid];
|
||||
|
||||
/*
|
||||
* Locate the first glyph corresponding to the start character.
|
||||
* If we can't find it, we return a zero length range at the end.
|
||||
* If it doesn't exist, we either have a zero length range at the end.
|
||||
* or we must return a not found marker.
|
||||
*/
|
||||
if (_JumpToChar(self, charRange.location) == NO)
|
||||
{
|
||||
if (actualCharRange != 0)
|
||||
if (charRange.location == _CharEnd(self))
|
||||
{
|
||||
actualCharRange->location = charRange.location;
|
||||
actualCharRange->length = 0;
|
||||
cRange = NSMakeRange(charRange.location, 0);
|
||||
gRange = NSMakeRange(numGlyphs, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
cRange = NSMakeRange(NSNotFound, 0);
|
||||
gRange = NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
return NSMakeRange(numGlyphs, 0);
|
||||
}
|
||||
gRange.location = _GlyphIndex(self);
|
||||
|
||||
/*
|
||||
* Adjust start character if necessary.
|
||||
*/
|
||||
pos = _CharIndex(self);
|
||||
if (pos < cRange.location)
|
||||
{
|
||||
cRange.length += (cRange.location - pos);
|
||||
cRange.location = pos;
|
||||
}
|
||||
|
||||
if (charRange.length == 0)
|
||||
{
|
||||
/*
|
||||
* For a zero length range, we don't need to locate an end character.
|
||||
*/
|
||||
gRange.length = 0;
|
||||
}
|
||||
else if (NSMaxRange(charRange) == [_textStorage length])
|
||||
{
|
||||
/*
|
||||
* Special case - range extends to end of text storage.
|
||||
*/
|
||||
gRange.length = numGlyphs - gRange.location;
|
||||
}
|
||||
else
|
||||
{
|
||||
gRange.location = _GlyphIndex(self);
|
||||
|
||||
/*
|
||||
* Locate the glyph immediately beyond the range,
|
||||
* and calculate the length of the range from that.
|
||||
* Adjust start character if necessary. The glyph may have a lower
|
||||
* index if the start char is part of a composed character sequence.
|
||||
*/
|
||||
_JumpToChar(self, NSMaxRange(charRange));
|
||||
pos = _GlyphIndex(self);
|
||||
gRange.length = pos - gRange.location;
|
||||
pos = _CharIndex(self);
|
||||
cRange.length = pos - cRange.location;
|
||||
if (pos < cRange.location)
|
||||
{
|
||||
cRange.length += (cRange.location - pos);
|
||||
cRange.location = pos;
|
||||
}
|
||||
|
||||
if (charRange.length == 0)
|
||||
{
|
||||
/*
|
||||
* For a zero length range, we don't need to locate an end character.
|
||||
*/
|
||||
cRange.length = 0; // May have been lengthened above.
|
||||
gRange.length = 0;
|
||||
}
|
||||
else if (NSMaxRange(charRange) == [_textStorage length])
|
||||
{
|
||||
/*
|
||||
* Special case - range extends to end of text storage.
|
||||
*/
|
||||
gRange.length = numGlyphs - gRange.location;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Locate the glyph immediately beyond the range,
|
||||
* and calculate the length of the range from that.
|
||||
*/
|
||||
_JumpToChar(self, NSMaxRange(charRange));
|
||||
pos = _GlyphIndex(self);
|
||||
gRange.length = pos - gRange.location;
|
||||
pos = _CharIndex(self);
|
||||
cRange.length = pos - cRange.location;
|
||||
}
|
||||
}
|
||||
#if ALL_CHECKS
|
||||
if (NSEqualRanges(gRange, charRange) == NO)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
gRange = charRange;
|
||||
}
|
||||
if (NSEqualRanges(cRange, charRange) == NO)
|
||||
{
|
||||
missmatch(_cmd);
|
||||
cRange = charRange;
|
||||
}
|
||||
#endif
|
||||
if (actualCharRange != 0)
|
||||
{
|
||||
*actualCharRange = cRange;
|
||||
}
|
||||
return gRange;
|
||||
_GLog(self,_cmd);
|
||||
#else
|
||||
// Currently gyphIndex is the same as character index
|
||||
if (actualCharRange != NULL)
|
||||
{
|
||||
*actualCharRange = charRange;
|
||||
}
|
||||
return charRange;
|
||||
gRange = charRange;
|
||||
#endif
|
||||
return gRange;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2167,6 +2311,7 @@ _Sane(self);
|
|||
{
|
||||
GSGlyphAttrs attrs;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (_JumpToGlyph(self, glyphIndex) == NO)
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
@ -2204,6 +2349,7 @@ _Sane(self);
|
|||
attrs.inscription = anInt;
|
||||
}
|
||||
_SetAttrs(self, attrs);
|
||||
_GLog(self,_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2218,6 +2364,7 @@ _Sane(self);
|
|||
{
|
||||
GSGlyphAttrs attrs;
|
||||
|
||||
_GLog(self,_cmd);
|
||||
if (_JumpToGlyph(self, glyphIndex) == NO)
|
||||
{
|
||||
[NSException raise: NSRangeException
|
||||
|
|
|
@ -1520,7 +1520,7 @@ static NSNotificationCenter *nc;
|
|||
return;
|
||||
}
|
||||
|
||||
charRange = NSMakeRange (_selected_range.location, 1);
|
||||
charRange = NSMakeRange (_selected_range.location, 0);
|
||||
glyphRange = [_layoutManager glyphRangeForCharacterRange: charRange
|
||||
actualCharacterRange: NULL];
|
||||
glyphIndex = glyphRange.location;
|
||||
|
|
Loading…
Reference in a new issue