Implement extra line fragment handling.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@15968 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2003-02-16 03:18:35 +00:00
parent 6027271a4f
commit 4dc81ab769
5 changed files with 157 additions and 28 deletions

View file

@ -1,3 +1,16 @@
2003-02-16 04:14 Alexander Malmberg <alexander@malmberg.org>
* Headers/gnustep/gui/GSLayoutManager.h, Source/GSLayoutManager.m:
Add methods for setting and getting the extra line fragment
information.
* Source/GSHorizontalTypesetter.m (-layoutLineNewParagraph:): Set
the extra line fragment information as required.
* Source/NSLayoutManager.m: Use the extra line fragment information
to position the insertion point properly when it's placed after the
last character in the text.
2003-02-15 18:22 Alexander Malmberg <alexander@malmberg.org>
* Headers/gnustep/gui/NSTextView.h, Source/NSLayoutManager.m,

View file

@ -266,6 +266,21 @@ manager might be substituting screen fonts. */
effectiveRange: (NSRange *)effectiveGlyphRange;
/*
The typesetter may set this to mark where the rectangle the insertion point
is to be placed if the insertion point is beyond the last character of the
text. The extra text container is reset to nil any time layout is
invalidated.
*/
-(void) setExtraLineFragmentRect: (NSRect)linefrag
usedRect: (NSRect)used
textContainer: (NSTextContainer *)tc;
-(NSRect) extraLineFragmentRect;
-(NSRect) extraLineFragmentUsedRect;
-(NSTextContainer *) extraLineFragmentTextContainer;
/* Extension, but without this, there's no way to get the starting locations
of the nominally spaced glyphs. */
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex

View file

@ -187,10 +187,10 @@ the last time or not, we wouldn't need to clear the cache every time */
cache = realloc(cache,sizeof(glyph_cache_t) * cache_size);
}
for (g = &cache[cache_length];cache_length < new_length;cache_length++,g++)
for (g = &cache[cache_length]; cache_length < new_length; cache_length++, g++)
{
g->g = [curLayoutManager glyphAtIndex: cache_base + cache_length
isValidIndex: &valid];
isValidIndex: &valid];
if (!valid)
{
at_end = YES;
@ -444,9 +444,9 @@ restart:
tindent = [curTextContainer containerSize].width + tindent;
remain = NSMakeRect(hindent,
curPoint.y,
tindent - hindent,
line_height + [curParagraphStyle lineSpacing]);
curPoint.y,
tindent - hindent,
line_height + [curParagraphStyle lineSpacing]);
}
/*
@ -518,6 +518,8 @@ restart:
/*
Main glyph layout loop.
*/
/* TODO: handling of newParagraph is ugly. must be set on all exits
from this loop */
while (1)
{
// printf("at %3i+%3i\n",cache_base,i);
@ -530,10 +532,16 @@ restart:
if (i >= cache_length)
{
if (at_end)
break;
{
newParagraph = NO;
break;
}
[self _cacheGlyphs: cache_length + 16];
if (i == cache_length)
break;
if (i >= cache_length)
{
newParagraph = NO;
break;
}
g = cache + i;
}
@ -600,7 +608,10 @@ restart:
prev_had_non_nominal_width = NO;
if (ch == 0xa)
break;
{
newParagraph = YES;
break;
}
if (ch == 0x9)
{
@ -810,7 +821,10 @@ restart:
lf++;
lfi++;
if (lfi == num_line_frags)
break;
{
newParagraph = NO;
break;
}
first_glyph = i;
}
else
@ -843,8 +857,6 @@ restart:
[self rightAlignLine: line_frags : num_line_frags];
else if ([curParagraphStyle alignment] == NSCenterTextAlignment)
[self centerAlignLine: line_frags : num_line_frags];
newParagraph = YES;
}
else
{
@ -857,7 +869,6 @@ restart:
[self centerAlignLine: line_frags : num_line_frags];
lfi--;
newParagraph = NO;
}
/* Layout is complete. Package it and give it to the layout manager. */
@ -930,8 +941,52 @@ restart:
line_frags = NULL;
}
/* TODO: if we're really at the end, we should probably set the extra
line frag stuff here */
/* Check if we're at the end. */
{
BOOL valid;
[curLayoutManager glyphAtIndex: curGlyph
isValidIndex: &valid];
if (!valid)
{
/*
We've typeset all glyphs, and thus return 2. If we ended with a
new-line, we set the extra line frag rect here so the insertion point
will be properly positioned after a trailing newline in the text.
*/
if (newParagraph)
{
NSRect r, r2, remain;
float hindent, tindent;
hindent = [curParagraphStyle firstLineHeadIndent];
tindent = [curParagraphStyle tailIndent];
if (tindent <= 0.0)
tindent = [curTextContainer containerSize].width + tindent;
line_height = [curFont defaultLineHeightForFont];
r = NSMakeRect(hindent,
curPoint.y,
tindent - hindent,
line_height + [curParagraphStyle lineSpacing]);
r = [curTextContainer lineFragmentRectForProposedRect: r
sweepDirection: NSLineSweepRight
movementDirection: NSLineMoveDown
remainingRect: &remain];
if (!NSEqualRects(r, NSZeroRect))
{
r2 = r;
r2.size.width = 1;
[curLayoutManager setExtraLineFragmentRect: r
usedRect: r2
textContainer: curTextContainer];
}
}
return 2;
}
}
if (newParagraph)
return 3;
else

View file

@ -1901,6 +1901,12 @@ forStartOfGlyphRange: (NSRange)glyphRange
used = NSZeroRect;
for (i = 0, lf = tc->linefrags; i < tc->num_linefrags; i++, lf++)
used = NSUnionRect(used, lf->used_rect);
if (container == extra_textcontainer)
{
used = NSUnionRect(used, extra_used_rect);
}
return used;
}
@ -2024,6 +2030,32 @@ forStartOfGlyphRange: (NSRange)glyphRange
*gindex = [self firstUnlaidGlyphIndex];
}
-(void) setExtraLineFragmentRect: (NSRect)linefrag
usedRect: (NSRect)used
textContainer: (NSTextContainer *)tc
{
extra_rect = linefrag;
extra_used_rect = used;
extra_textcontainer = tc;
}
-(NSRect) extraLineFragmentRect
{
return extra_rect;
}
-(NSRect) extraLineFragmentUsedRect
{
return extra_used_rect;
}
-(NSTextContainer *) extraLineFragmentTextContainer
{
return extra_textcontainer;
}
@end

View file

@ -589,13 +589,8 @@ Insertion point positioning and movement.
{
if (cindex == [[_textStorage string] length])
{
if (!cindex)
{
*fraction = 0.0;
return (unsigned int)-1;
}
*fraction = 1.0;
return [self numberOfGlyphs] - 1;
*fraction = 0.0;
return (unsigned int)-1;
}
else
{
@ -639,12 +634,29 @@ has the same y origin and height as the line frag rect it is in.
fractionThrough: &fraction_through];
if (glyph_index == (unsigned int)-1)
{
if (num_textcontainers > 0)
*textContainer = 0;
else
*textContainer = -1;
/* TODO: use extra rect, etc. */
return NSMakeRect(1,1,1,13);
/* Need complete layout information. */
[self _doLayout];
if (extra_textcontainer)
{
for (tc = textcontainers, i = 0; i < num_textcontainers; i++, tc++)
if (tc == textcontainers)
break;
NSAssert(i < num_textcontainers, @"invalid extraTextContainer");
*textContainer = i;
r = extra_rect;
r.size.width = 1;
return r;
}
glyph_index = [self numberOfGlyphs] - 1;
if (glyph_index == (unsigned int)-1)
{
/* No information is available. */
/* will be -1 if there are no text containers */
*textContainer = num_textcontainers - 1;
return NSMakeRect(1, 1, 1, 15);
}
fraction_through = 1.0;
}
[self _doLayoutToGlyph: glyph_index];
@ -861,6 +873,8 @@ has the same y origin and height as the line frag rect it is in.
}
else
{
if (i == tc->num_linefrags)
i--, lf--;
/* Find the target line. Move at least (should be up to?)
distance, and at least one line. */
for (; i >= 0; i--, lf--)