From 9ea1c79aa013385f921445395f57fbd45b0ea014 Mon Sep 17 00:00:00 2001 From: Asger Ottar Alstrup Date: Sun, 27 Jul 2003 10:42:11 +0000 Subject: [PATCH] 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 --- src/ChangeLog | 5 +++++ src/paragraph.C | 15 +++++++++++++++ src/paragraph.h | 7 +++++++ src/text.C | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c1e29d1852..d03913f0fb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2003-07-27 Asger Alstrup + + * text.C (fill): Optimise algorithm to exploit that we can reuse + the LyXFont for many characters. + 2003-07-26 Asger Alstrup * text2.C (metrics): change a brain-dead algorithm to a smarter one. diff --git a/src/paragraph.C b/src/paragraph.C index 84d8b2350d..daeec8dd78 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -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 diff --git a/src/paragraph.h b/src/paragraph.h index daa2056cb8..6581b639ed 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -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; /// diff --git a/src/text.C b/src/text.C index 8552f65777..42667d24af 100644 --- a/src/text.C +++ b/src/text.C @@ -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); + } } } -- 2.39.2