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> 2005-06-09 Angus Leeming <leeming@lyx.org>
* converter.C (convert): Don't forget "outfile = real_outfile" as * 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) lyx::pos_type pos)
: text_(text), par_(par), pos_(pos), : text_(text), par_(par), pos_(pos),
font_(text.getFont(par, pos)), font_(text.getFont(par, pos)),
endspan_(par.getEndPosOfFontSpan(pos)), endspan_(par.getFontSpan(pos).second),
bodypos_(par.beginOfBody()) bodypos_(par.beginOfBody())
{} {}
@ -44,7 +44,7 @@ FontIterator & FontIterator::operator++()
++pos_; ++pos_;
if (pos_ > endspan_ || pos_ == bodypos_) { if (pos_ > endspan_ || pos_ == bodypos_) {
font_ = text_.getFont(par_, pos_); font_ = text_.getFont(par_, pos_);
endspan_ = par_.getEndPosOfFontSpan(pos_); endspan_ = par_.getFontSpan(pos_).second;
} }
return *this; 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()); BOOST_ASSERT(pos <= size());
lyx::pos_type start = 0;
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin(); Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end(); Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
for (; cit != end; ++cit) for (; cit != end; ++cit) {
if (cit->pos() >= pos) 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. // This should not happen, but if so, we take no chances.
//lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!" //lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!"
// << endl; // << endl;
return pos; return std::make_pair(pos, pos);
} }

View File

@ -29,6 +29,7 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <string> #include <string>
#include <utility>
class Buffer; class Buffer;
class BufferParams; class BufferParams;
@ -280,11 +281,12 @@ public:
LyXFont const & outerfont) const; LyXFont const & outerfont) const;
/** /**
* The font returned by the above functions is the same in a * The font returned by the above functions is the same in a
* span of characters. This method will return the last position * span of characters. This method will return the first and
* in the paragraph for which that font is the same. * the last last positions in the paragraph for which that
* This can be used to avoid unnecessary calls to getFont. * 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. /// this is a bottleneck.
value_type getChar(lyx::pos_type pos) const value_type getChar(lyx::pos_type pos) const

View File

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