mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-24 06:28:54 +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
6027271a4f
commit
4dc81ab769
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>
|
||||
|
||||
* Headers/gnustep/gui/NSTextView.h, Source/NSLayoutManager.m,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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--)
|
||||
|
|
Loading…
Reference in a new issue