When calculating fill, exploit data structure to avoid superfluous calls to getFont.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7376 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Asger Ottar Alstrup 2003-07-27 10:42:11 +00:00
parent 89c62d0625
commit 9ea1c79aa0
4 changed files with 59 additions and 3 deletions

View File

@ -1,3 +1,8 @@
2003-07-27 Asger Alstrup <alstrup@local>
* text.C (fill): Optimise algorithm to exploit that we can reuse
the LyXFont for many characters.
2003-07-26 Asger Alstrup <alstrup@local>
* text2.C (metrics): change a brain-dead algorithm to a smarter one.

View File

@ -411,6 +411,21 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
return retfont;
}
lyx::pos_type
Paragraph::getEndPosOfFontSpan(lyx::pos_type pos) const
{
Assert(pos <= size());
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
for (; cit != end; ++cit) {
if (cit->pos() >= pos)
return cit->pos();
}
// This should not happen, but if so, we take no chances.
return pos;
}
// Gets uninstantiated font setting at position 0
LyXFont const Paragraph::getFirstFontSettings() const

View File

@ -222,6 +222,13 @@ public:
LyXFont const & outerfont) const;
LyXFont const getLabelFont(BufferParams const &,
LyXFont const & outerfont) const;
/**
* The font returned by the above functions is the same in a
* span of characters. This method will return the last position
* in the paragraph for which that font is the same.
* This can be used to avoid unnecessary calls to getFont.
*/
lyx::pos_type getEndPosOfFontSpan(lyx::pos_type pos) const;
///
value_type getChar(lyx::pos_type pos) const;
///

View File

@ -934,7 +934,10 @@ int LyXText::fill(RowList::iterator row, int paper_width) const
pos_type const body_pos = pit->beginningOfBody();
pos_type i = row->pos();
if (! pit->empty()) {
if (! pit->empty() && i <= last) {
// We re-use the font resolution for the entire span when possible
LyXFont font = getFont(bv()->buffer(), pit, i);
lyx::pos_type endPosOfFontSpan = pit->getEndPosOfFontSpan(i);
while (i <= last) {
if (body_pos > 0 && i == body_pos) {
w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), pit));
@ -944,7 +947,30 @@ int LyXText::fill(RowList::iterator row, int paper_width) const
if (w < left_margin)
w = left_margin;
}
w += singleWidth(pit, i);
{ // Manual inlined an optimised version of the common case of "w += singleWidth(pit, i);"
char const c = pit->getChar(i);
if (IsPrintable(c)) {
if (i > endPosOfFontSpan) {
// We need to get the next font
font = getFont(bv()->buffer(), pit, i);
endPosOfFontSpan = pit->getEndPosOfFontSpan(i);
}
if (! font.language()->RightToLeft()) {
w += font_metrics::width(c, font);
} else {
// Fall-back to the normal case
w += singleWidth(pit, i, c);
// And flush font cache
endPosOfFontSpan = 0;
}
} else {
// Fall-back to the normal case
w += singleWidth(pit, i, c);
// And flush font cache
endPosOfFontSpan = 0;
}
}
++i;
}
}
@ -1096,7 +1122,10 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
#endif
}
} else {
maxwidth += singleWidth(pit, pos);
// Manual inlined optimised version of common case of "maxwidth += singleWidth(pit, pos);"
char const c = pit->getChar(pos);
maxwidth += singleWidth(pit, pos, c);
}
}
}