mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 06:51:08 +00:00
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:
parent
77a10cb02f
commit
c12bd68ed6
2 changed files with 131 additions and 98 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue