reduce number of calls to LyXText::getFont

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10044 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2005-06-10 14:55:01 +00:00
parent 62022d5441
commit 6b264151e1
5 changed files with 67 additions and 49 deletions

View File

@ -1,3 +1,19 @@
2005-06-09 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* rowpainter.C (paintInset, paintHebrewComposeChar)
(paintArabicComposeChar, paintChars): add a LyXFont argument.
(paintChars): use getFontSpan to reduce calls to getFont to a
minimum; use Paragraph::lookupChange instead of isXXXText.
(paintForeignMark): rename LyXFont argument.
(paintFromPos): pass a LyXFont object to the various paintXXX
methods.
* FontIterator.C (FontIterator, operator++): use
Paragraph::getFontSpan
* paragraph.C (getFontSpan): replace getEndOfFontSpan with a
version that returns the font span as a pair.
2005-06-09 Angus Leeming <leeming@lyx.org>
* converter.C (convert): Don't forget "outfile = real_outfile" as

View File

@ -22,7 +22,7 @@ FontIterator::FontIterator(LyXText const & text, Paragraph const & par,
lyx::pos_type pos)
: text_(text), par_(par), pos_(pos),
font_(text.getFont(par, pos)),
endspan_(par.getEndPosOfFontSpan(pos)),
endspan_(par.getFontSpan(pos).second),
bodypos_(par.beginOfBody())
{}
@ -44,7 +44,7 @@ FontIterator & FontIterator::operator++()
++pos_;
if (pos_ > endspan_ || pos_ == bodypos_) {
font_ = text_.getFont(par_, pos_);
endspan_ = par_.getEndPosOfFontSpan(pos_);
endspan_ = par_.getFontSpan(pos_).second;
}
return *this;
}

View File

@ -346,20 +346,23 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
}
lyx::pos_type Paragraph::getEndPosOfFontSpan(lyx::pos_type pos) const
std::pair<lyx::pos_type, lyx::pos_type> Paragraph::getFontSpan(lyx::pos_type pos) const
{
BOOST_ASSERT(pos <= size());
lyx::pos_type start = 0;
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
for (; cit != end; ++cit)
for (; cit != end; ++cit) {
if (cit->pos() >= pos)
return cit->pos();
return std::make_pair(start, cit->pos());
start = cit->pos() + 1;
}
// This should not happen, but if so, we take no chances.
//lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!"
// << endl;
return pos;
return std::make_pair(pos, pos);
}

View File

@ -29,6 +29,7 @@
#include <boost/assert.hpp>
#include <string>
#include <utility>
class Buffer;
class BufferParams;
@ -280,11 +281,12 @@ public:
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.
* span of characters. This method will return the first and
* the last last positions 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;
std::pair<lyx::pos_type, lyx::pos_type> getFontSpan(lyx::pos_type pos) const;
///
/// this is a bottleneck.
value_type getChar(lyx::pos_type pos) const

View File

@ -69,13 +69,14 @@ public:
void paintText();
private:
void paintForeignMark(double orig_x, LyXFont const & orig_font);
void paintHebrewComposeChar(lyx::pos_type & vpos);
void paintArabicComposeChar(lyx::pos_type & vpos);
void paintChars(lyx::pos_type & vpos, bool hebrew, bool arabic);
void paintForeignMark(double orig_x, LyXFont const & font);
void paintHebrewComposeChar(lyx::pos_type & vpos, LyXFont const & font);
void paintArabicComposeChar(lyx::pos_type & vpos, LyXFont const & font);
void paintChars(lyx::pos_type & vpos, LyXFont font,
bool hebrew, bool arabic);
int paintAppendixStart(int y);
void paintFromPos(lyx::pos_type & vpos);
void paintInset(lyx::pos_type const pos);
void paintInset(lyx::pos_type const pos, LyXFont const & font);
/// return left margin
int leftMargin() const;
@ -173,12 +174,12 @@ int RowPainter::leftMargin() const
}
void RowPainter::paintInset(pos_type const pos)
void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
{
InsetBase const * inset = par_.getInset(pos);
BOOST_ASSERT(inset);
PainterInfo pi(const_cast<BufferView *>(&bv_), pain_);
pi.base.font = getFont(pos);
pi.base.font = font;
pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
theCoords.insets().add(inset, int(x_), yo_);
inset->drawSelection(pi, int(x_), yo_);
@ -187,7 +188,7 @@ void RowPainter::paintInset(pos_type const pos)
}
void RowPainter::paintHebrewComposeChar(pos_type & vpos)
void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font)
{
pos_type pos = text_.bidi.vis2log(vpos);
@ -198,7 +199,6 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
str += c;
++vpos;
LyXFont const & font = getFont(pos);
int const width = font_metrics::width(c, font);
int dx = 0;
@ -221,7 +221,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
}
void RowPainter::paintArabicComposeChar(pos_type & vpos)
void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font)
{
pos_type pos = text_.bidi.vis2log(vpos);
string str;
@ -232,7 +232,6 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
str += c;
++vpos;
LyXFont const & font = getFont(pos);
int const width = font_metrics::width(c, font);
int dx = 0;
@ -251,11 +250,14 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
}
void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
void RowPainter::paintChars(pos_type & vpos, LyXFont font,
bool hebrew, bool arabic)
{
pos_type pos = text_.bidi.vis2log(vpos);
pos_type const end = row_.endpos();
LyXFont orig_font = getFont(pos);
std::pair<lyx::pos_type, lyx::pos_type> const font_span
= par_.getFontSpan(pos);
Change::Type const prev_change = par_.lookupChange(pos);
// first character
string str;
@ -265,56 +267,51 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
str[0] = par_.transformChar(c, pos);
}
bool prev_struckout = isDeletedText(par_, pos);
bool prev_newtext = isInsertedText(par_, pos);
// collect as much similar chars as we can
for (++vpos; vpos < end && (pos = text_.bidi.vis2log(vpos)) >= 0; ++vpos) {
for (++vpos ; vpos < end ; ++vpos) {
pos = text_.bidi.vis2log(vpos);
if (pos < font_span.first || pos > font_span.second)
break;
if (prev_change != par_.lookupChange(pos))
break;
char c = par_.getChar(pos);
if (!IsPrintableNonspace(c))
break;
if (prev_struckout != isDeletedText(par_, pos))
break;
if (prev_newtext != isInsertedText(par_, pos))
break;
if (arabic && Encodings::IsComposeChar_arabic(c))
break;
if (hebrew && Encodings::IsComposeChar_hebrew(c))
break;
if (orig_font != getFont(pos))
break;
if (arabic)
c = par_.transformChar(c, pos);
str += c;
}
if (prev_struckout)
orig_font.setColor(LColor::strikeout);
else if (prev_newtext)
orig_font.setColor(LColor::newtext);
if (prev_change == Change::DELETED)
font.setColor(LColor::strikeout);
else if (prev_change == Change::INSERTED)
font.setColor(LColor::newtext);
// Draw text and set the new x position
//lyxerr << "paint row: yo_ " << yo_ << "\n";
pain_.text(int(x_), yo_, str, orig_font);
x_ += font_metrics::width(str, orig_font);
pain_.text(int(x_), yo_, str, font);
x_ += font_metrics::width(str, font);
}
void RowPainter::paintForeignMark(double orig_x, LyXFont const & orig_font)
void RowPainter::paintForeignMark(double orig_x, LyXFont const & font)
{
if (!lyxrc.mark_foreign_language)
return;
if (orig_font.language() == latex_language)
if (font.language() == latex_language)
return;
if (orig_font.language() == bv_.buffer()->params().language)
if (font.language() == bv_.buffer()->params().language)
return;
int const y = yo_ + 1;
@ -333,7 +330,7 @@ void RowPainter::paintFromPos(pos_type & vpos)
char const c = par_.getChar(pos);
if (c == Paragraph::META_INSET) {
paintInset(pos);
paintInset(pos, orig_font);
++vpos;
paintForeignMark(orig_x, orig_font);
return;
@ -352,11 +349,11 @@ void RowPainter::paintFromPos(pos_type & vpos)
if ((!hebrew && !arabic)
|| (hebrew && !Encodings::IsComposeChar_hebrew(c))
|| (arabic && !Encodings::IsComposeChar_arabic(c))) {
paintChars(vpos, hebrew, arabic);
paintChars(vpos, orig_font, hebrew, arabic);
} else if (hebrew) {
paintHebrewComposeChar(vpos);
paintHebrewComposeChar(vpos, orig_font);
} else if (arabic) {
paintArabicComposeChar(vpos);
paintArabicComposeChar(vpos, orig_font);
}
paintForeignMark(orig_x, orig_font);