mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 18:50:48 +00:00
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:
parent
b95e8bf3f4
commit
56a6fbe50d
5 changed files with 157 additions and 28 deletions
13
ChangeLog
13
ChangeLog
|
@ -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>
|
2003-02-15 18:22 Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
|
||||||
* Headers/gnustep/gui/NSTextView.h, Source/NSLayoutManager.m,
|
* Headers/gnustep/gui/NSTextView.h, Source/NSLayoutManager.m,
|
||||||
|
|
|
@ -266,6 +266,21 @@ manager might be substituting screen fonts. */
|
||||||
effectiveRange: (NSRange *)effectiveGlyphRange;
|
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
|
/* Extension, but without this, there's no way to get the starting locations
|
||||||
of the nominally spaced glyphs. */
|
of the nominally spaced glyphs. */
|
||||||
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex
|
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex
|
||||||
|
|
|
@ -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);
|
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
|
g->g = [curLayoutManager glyphAtIndex: cache_base + cache_length
|
||||||
isValidIndex: &valid];
|
isValidIndex: &valid];
|
||||||
if (!valid)
|
if (!valid)
|
||||||
{
|
{
|
||||||
at_end = YES;
|
at_end = YES;
|
||||||
|
@ -444,9 +444,9 @@ restart:
|
||||||
tindent = [curTextContainer containerSize].width + tindent;
|
tindent = [curTextContainer containerSize].width + tindent;
|
||||||
|
|
||||||
remain = NSMakeRect(hindent,
|
remain = NSMakeRect(hindent,
|
||||||
curPoint.y,
|
curPoint.y,
|
||||||
tindent - hindent,
|
tindent - hindent,
|
||||||
line_height + [curParagraphStyle lineSpacing]);
|
line_height + [curParagraphStyle lineSpacing]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -518,6 +518,8 @@ restart:
|
||||||
/*
|
/*
|
||||||
Main glyph layout loop.
|
Main glyph layout loop.
|
||||||
*/
|
*/
|
||||||
|
/* TODO: handling of newParagraph is ugly. must be set on all exits
|
||||||
|
from this loop */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// printf("at %3i+%3i\n",cache_base,i);
|
// printf("at %3i+%3i\n",cache_base,i);
|
||||||
|
@ -530,10 +532,16 @@ restart:
|
||||||
if (i >= cache_length)
|
if (i >= cache_length)
|
||||||
{
|
{
|
||||||
if (at_end)
|
if (at_end)
|
||||||
break;
|
{
|
||||||
|
newParagraph = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
[self _cacheGlyphs: cache_length + 16];
|
[self _cacheGlyphs: cache_length + 16];
|
||||||
if (i == cache_length)
|
if (i >= cache_length)
|
||||||
break;
|
{
|
||||||
|
newParagraph = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
g = cache + i;
|
g = cache + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +608,10 @@ restart:
|
||||||
prev_had_non_nominal_width = NO;
|
prev_had_non_nominal_width = NO;
|
||||||
|
|
||||||
if (ch == 0xa)
|
if (ch == 0xa)
|
||||||
break;
|
{
|
||||||
|
newParagraph = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ch == 0x9)
|
if (ch == 0x9)
|
||||||
{
|
{
|
||||||
|
@ -810,7 +821,10 @@ restart:
|
||||||
lf++;
|
lf++;
|
||||||
lfi++;
|
lfi++;
|
||||||
if (lfi == num_line_frags)
|
if (lfi == num_line_frags)
|
||||||
break;
|
{
|
||||||
|
newParagraph = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
first_glyph = i;
|
first_glyph = i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -843,8 +857,6 @@ restart:
|
||||||
[self rightAlignLine: line_frags : num_line_frags];
|
[self rightAlignLine: line_frags : num_line_frags];
|
||||||
else if ([curParagraphStyle alignment] == NSCenterTextAlignment)
|
else if ([curParagraphStyle alignment] == NSCenterTextAlignment)
|
||||||
[self centerAlignLine: line_frags : num_line_frags];
|
[self centerAlignLine: line_frags : num_line_frags];
|
||||||
|
|
||||||
newParagraph = YES;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -857,7 +869,6 @@ restart:
|
||||||
[self centerAlignLine: line_frags : num_line_frags];
|
[self centerAlignLine: line_frags : num_line_frags];
|
||||||
|
|
||||||
lfi--;
|
lfi--;
|
||||||
newParagraph = NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Layout is complete. Package it and give it to the layout manager. */
|
/* Layout is complete. Package it and give it to the layout manager. */
|
||||||
|
@ -930,8 +941,52 @@ restart:
|
||||||
line_frags = NULL;
|
line_frags = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: if we're really at the end, we should probably set the extra
|
/* Check if we're at the end. */
|
||||||
line frag stuff here */
|
{
|
||||||
|
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)
|
if (newParagraph)
|
||||||
return 3;
|
return 3;
|
||||||
else
|
else
|
||||||
|
|
|
@ -1901,6 +1901,12 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
used = NSZeroRect;
|
used = NSZeroRect;
|
||||||
for (i = 0, lf = tc->linefrags; i < tc->num_linefrags; i++, lf++)
|
for (i = 0, lf = tc->linefrags; i < tc->num_linefrags; i++, lf++)
|
||||||
used = NSUnionRect(used, lf->used_rect);
|
used = NSUnionRect(used, lf->used_rect);
|
||||||
|
|
||||||
|
if (container == extra_textcontainer)
|
||||||
|
{
|
||||||
|
used = NSUnionRect(used, extra_used_rect);
|
||||||
|
}
|
||||||
|
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2024,6 +2030,32 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
*gindex = [self firstUnlaidGlyphIndex];
|
*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
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -589,13 +589,8 @@ Insertion point positioning and movement.
|
||||||
{
|
{
|
||||||
if (cindex == [[_textStorage string] length])
|
if (cindex == [[_textStorage string] length])
|
||||||
{
|
{
|
||||||
if (!cindex)
|
*fraction = 0.0;
|
||||||
{
|
return (unsigned int)-1;
|
||||||
*fraction = 0.0;
|
|
||||||
return (unsigned int)-1;
|
|
||||||
}
|
|
||||||
*fraction = 1.0;
|
|
||||||
return [self numberOfGlyphs] - 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -639,12 +634,29 @@ has the same y origin and height as the line frag rect it is in.
|
||||||
fractionThrough: &fraction_through];
|
fractionThrough: &fraction_through];
|
||||||
if (glyph_index == (unsigned int)-1)
|
if (glyph_index == (unsigned int)-1)
|
||||||
{
|
{
|
||||||
if (num_textcontainers > 0)
|
/* Need complete layout information. */
|
||||||
*textContainer = 0;
|
[self _doLayout];
|
||||||
else
|
if (extra_textcontainer)
|
||||||
*textContainer = -1;
|
{
|
||||||
/* TODO: use extra rect, etc. */
|
for (tc = textcontainers, i = 0; i < num_textcontainers; i++, tc++)
|
||||||
return NSMakeRect(1,1,1,13);
|
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];
|
[self _doLayoutToGlyph: glyph_index];
|
||||||
|
@ -861,6 +873,8 @@ has the same y origin and height as the line frag rect it is in.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (i == tc->num_linefrags)
|
||||||
|
i--, lf--;
|
||||||
/* Find the target line. Move at least (should be up to?)
|
/* Find the target line. Move at least (should be up to?)
|
||||||
distance, and at least one line. */
|
distance, and at least one line. */
|
||||||
for (; i >= 0; i--, lf--)
|
for (; i >= 0; i--, lf--)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue