Optimize -advancementForGlyph: handling.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@19859 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2004-08-09 22:14:17 +00:00
parent 77a10cb02f
commit c12bd68ed6
2 changed files with 131 additions and 98 deletions

View file

@ -1,3 +1,11 @@
2004-08-10 00:06 Alexander Malmberg <alexander@malmberg.org>
* Source/GSHorizontalTypesetter.m: Formatting cleanups.
(-_reuseSoftInvalidatedLayout): New method. Contains soft invalidated
layout info handling, moved here from ...
(-layoutLineNewParagraph:): ...here. Cache the imp for
-advancementForGlyph: and send it directly to the fontInfo.
2004-08-09 21:45 Alexander Malmberg <alexander@malmberg.org>
* Headers/Additions/GNUstepGUI/GSLayoutManager_internal.h: Add

View file

@ -206,7 +206,6 @@ the last time or not, we wouldn't need to clear the cache every time */
break;
}
g->char_index = [curLayoutManager characterIndexForGlyphAtIndex: cache_base + cache_length];
// printf("cache glyph %i, char %i\n",cache_base + cache_length,g->char_index);
if (g->char_index >= paragraphRange.location + paragraphRange.length)
{
at_end = YES;
@ -360,6 +359,70 @@ typedef struct GSHorizontalTypesetter_line_frag_s
}
-(BOOL) _reuseSoftInvalidatedLayout
{
/*
We only handle the simple-horizontal-text-container case currently.
*/
NSRect r0, r;
NSSize shift;
int i;
unsigned int g, g2, first;
float container_height;
/*
Ask the layout manager for soft-invalidated layout for the current
glyph. If there is a set of line frags starting at the current glyph,
and we can get rects with the same size and horizontal position, we
tell the layout manager to use the soft-invalidated information.
*/
r0 = [curLayoutManager _softInvalidateLineFragRect: 0
firstGlyph: &first
nextGlyph: &g
inTextContainer: curTextContainer];
container_height = [curTextContainer containerSize].height;
if (!(curPoint.y + r0.size.height <= container_height))
return NO;
/*
We can shift the rects and still have things fit. Find all the line
frags in the line and shift them.
*/
shift.width = 0;
shift.height = curPoint.y - r0.origin.y;
i = 1;
curPoint.y = NSMaxY(r0) + shift.height;
for (; 1; i++)
{
r = [curLayoutManager _softInvalidateLineFragRect: i
firstGlyph: &first
nextGlyph: &g2
inTextContainer: curTextContainer];
/*
If there's a gap in soft invalidated information, we need to
fill it in before we can continue.
*/
if (first != g)
{
break;
}
if (NSIsEmptyRect(r) || NSMaxY(r) + shift.height > container_height)
break;
g = g2;
curPoint.y = NSMaxY(r) + shift.height;
}
[curLayoutManager _softInvalidateUseLineFrags: i
withShift: shift
inTextContainer: curTextContainer];
curGlyph = g;
return YES;
}
/*
Return values 0, 1, 2 are mostly the same as from
-layoutGlyphsInLayoutManager:.... Additions:
@ -409,67 +472,9 @@ Return values 0, 1, 2 are mostly the same as from
if ([curTextContainer isSimpleRectangularTextContainer] &&
[curLayoutManager _softInvalidateFirstGlyphInTextContainer: curTextContainer] == curGlyph)
{
/*
We only handle the simple-horizontal-text-container case currently.
*/
NSRect r0, r;
NSSize shift;
int i;
unsigned int g, g2, first;
float container_height;
/*
Ask the layout manager for soft-invalidated layout for the current
glyph. If there is a set of line frags starting at the current glyph,
and we can get rects with the same size and horizontal position, we
tell the layout manager to use the soft-invalidated information.
*/
r0 = [curLayoutManager _softInvalidateLineFragRect: 0
firstGlyph: &first
nextGlyph: &g
inTextContainer: curTextContainer];
container_height = [curTextContainer containerSize].height;
if (curPoint.y + r0.size.height <= container_height)
{
/*
We can shift the rects and still have things fit. Find all the line
frags in the line and shift them.
*/
shift.width = 0;
shift.height = curPoint.y - r0.origin.y;
i = 1;
curPoint.y = NSMaxY(r0) + shift.height;
for (; 1; i++)
{
r = [curLayoutManager _softInvalidateLineFragRect: i
firstGlyph: &first
nextGlyph: &g2
inTextContainer: curTextContainer];
/*
If there's a gap in soft invalidated information, we need to
fill it in before we can continue.
*/
if (first != g)
{
break;
}
if (NSIsEmptyRect(r) || NSMaxY(r) + shift.height > container_height)
break;
g = g2;
curPoint.y = NSMaxY(r) + shift.height;
}
[curLayoutManager _softInvalidateUseLineFrags: i
withShift: shift
inTextContainer: curTextContainer];
curGlyph = g;
if ([self _reuseSoftInvalidatedLayout])
return 4;
}
}
[self _cacheMoveTo: curGlyph];
@ -486,7 +491,9 @@ Return values 0, 1, 2 are mostly the same as from
float hindent, tindent;
if (!newParagraph || !curGlyph)
{
return 2;
}
/*
We aren't actually interested in the glyph data, but we want the
@ -572,8 +579,8 @@ Return values 0, 1, 2 are mostly the same as from
} \
} while (0)
restart:
// printf("start: at (%g %g) line_height = %g, baseline = %g\n",curPoint.x,curPoint.y,line_height,baseline);
restart: ;
{
float hindent, tindent = [curParagraphStyle tailIndent];
@ -640,6 +647,18 @@ restart:
NSPoint p;
NSFont *f = cache->font;
/*
TODO: This is kindof ugly, but -advancementForGlyph: is responsible for
~10% of execution time when handling huge amounts of text (according to
profiling, 2004-08-09). Would be cleaner to get rid of the font/fontInfo
indirection.
*/
id fontInfo = [f fontInfo];
NSSize (*advancementForGlyph)(id, SEL, NSGlyph)
= (NSSize(*)(id, SEL, NSGlyph))[fontInfo methodForSelector:
@selector(advancementForGlyph:)];
float f_ascender = [f ascender], f_descender = -[f descender];
NSGlyph last_glyph = NSNullGlyph;
@ -717,6 +736,9 @@ restart:
{
float new_height;
f = g->font;
fontInfo = [f fontInfo];
advancementForGlyph = (NSSize(*)(id, SEL, NSGlyph))
[fontInfo methodForSelector: @selector(advancementForGlyph:)];
f_ascender = [f ascender];
f_descender = -[f descender];
last_glyph = NSNullGlyph;
@ -922,7 +944,10 @@ restart:
}*/
last_p = g->pos = p;
g->size = [f advancementForGlyph: g->g]; /* only width is used */
/* Only the width is used. */
g->size = advancementForGlyph(fontInfo,
@selector(advancementForGlyph:),
g->g);
p.x += g->size.width;
}
@ -1187,11 +1212,11 @@ NS_DURING
NS_HANDLER
[lock unlock];
[localException raise];
ret=0; /* This is never reached, but it shuts up the compiler. */
NS_ENDHANDLER
[lock unlock];
return ret;
}
@end