fix bug 1795

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10321 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2005-07-18 12:13:32 +00:00
parent af5acb6dc7
commit f5e68ec257
8 changed files with 65 additions and 34 deletions

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.getFontSpan(pos).second),
endspan_(par.fontSpan(pos).last),
bodypos_(par.beginOfBody())
{}
@ -44,7 +44,7 @@ FontIterator & FontIterator::operator++()
++pos_;
if (pos_ > endspan_ || pos_ == bodypos_) {
font_ = text_.getFont(par_, pos_);
endspan_ = par_.getFontSpan(pos_).second;
endspan_ = par_.fontSpan(pos_).last;
}
return *this;
}

View File

@ -37,6 +37,8 @@ void CoordCache::clear()
arrays_.clear();
insets_.clear();
pars_.clear();
slices0_.clear();
slices1_.clear();
}

View File

@ -42,7 +42,6 @@ public:
int x_, y_;
};
template <class T> class CoordCacheBase {
public:
void clear()
@ -122,6 +121,8 @@ public:
typedef std::map<lyx::pit_type, Point> InnerParPosCache;
/// A map from a LyXText to the map of paragraphs to screen points
typedef std::map<LyXText const *, InnerParPosCache> ParPosCache;
/// A map from a CursorSlice to screen points
typedef std::map<LyXText const *, InnerParPosCache> SliceCache;
/// A map from MathArray to position on the screen
CoordCacheBase<MathArray> & arrays() { BOOST_ASSERT(updating); return arrays_; }
@ -132,14 +133,28 @@ public:
/// A map from (LyXText, paragraph) pair to screen positions
ParPosCache & parPos() { BOOST_ASSERT(updating); return pars_; }
ParPosCache const & getParPos() const { return pars_; }
///
SliceCache & slice(bool boundary)
{
BOOST_ASSERT(updating);
return boundary ? slices1_ : slices0_;
}
SliceCache const & getSlice(bool boundary) const
{
return boundary ? slices1_ : slices0_;
}
private:
/// MathArrays
CoordCacheBase<MathArray> arrays_;
// all insets
// All insets
CoordCacheBase<InsetBase> insets_;
// paragraph grouped by owning text
/// Paragraph grouped by owning text
ParPosCache pars_;
/// Used with boundary == 0
SliceCache slices0_;
/// Used with boundary == 1
SliceCache slices1_;
/**
* Debugging flag only: Set to true while the cache is being built.

View File

@ -339,7 +339,7 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
}
std::pair<lyx::pos_type, lyx::pos_type> Paragraph::getFontSpan(lyx::pos_type pos) const
FontSpan Paragraph::fontSpan(lyx::pos_type pos) const
{
BOOST_ASSERT(pos <= size());
lyx::pos_type start = 0;
@ -348,14 +348,14 @@ std::pair<lyx::pos_type, lyx::pos_type> Paragraph::getFontSpan(lyx::pos_type pos
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
for (; cit != end; ++cit) {
if (cit->pos() >= pos)
return std::make_pair(start, cit->pos());
return FontSpan(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 std::make_pair(pos, pos);
return FontSpan(pos, pos);
}

View File

@ -27,7 +27,6 @@
#include "support/types.h"
#include <string>
#include <utility>
class Buffer;
class BufferParams;
@ -47,6 +46,15 @@ class ParagraphParameters;
class TexRow;
class FontSpan {
public:
FontSpan() : first(0), last(0) {}
FontSpan(lyx::pos_type f, lyx::pos_type l) : first(f), last(l) {}
lyx::pos_type first;
lyx::pos_type last;
};
/// A Paragraph holds all text, attributes and insets in a text paragraph
class Paragraph {
public:
@ -279,11 +287,11 @@ public:
/**
* The font returned by the above functions is the same in a
* 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.
* the last positions in the paragraph for which that font is
* the same. This can be used to avoid unnecessary calls to
* getFont.
*/
std::pair<lyx::pos_type, lyx::pos_type> getFontSpan(lyx::pos_type pos) const;
FontSpan fontSpan(lyx::pos_type pos) const;
///
/// this is a bottleneck.
value_type getChar(lyx::pos_type pos) const { return text_[pos]; }

View File

@ -255,8 +255,7 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font,
{
pos_type pos = text_.bidi.vis2log(vpos);
pos_type const end = row_.endpos();
std::pair<lyx::pos_type, lyx::pos_type> const font_span
= par_.getFontSpan(pos);
FontSpan const font_span = par_.fontSpan(pos);
Change::Type const prev_change = par_.lookupChange(pos);
// first character
@ -270,7 +269,7 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font,
// collect as much similar chars as we can
for (++vpos ; vpos < end ; ++vpos) {
pos = text_.bidi.vis2log(vpos);
if (pos < font_span.first || pos > font_span.second)
if (pos < font_span.first || pos > font_span.last)
break;
if (prev_change != par_.lookupChange(pos))

View File

@ -701,24 +701,21 @@ void LyXText::rowBreakPoint(pit_type const pit, Row & row) const
pos_type i = pos;
for ( ; i < end; ++i, ++fi) {
char const c = par.getChar(i);
int thiswidth = singleWidth(par, i, c, *fi);
{
int thiswidth = singleWidth(par, i, c, *fi);
// add the auto-hfill from label end to the body
if (body_pos && i == body_pos) {
int add = font_metrics::width(layout->labelsep, getLabelFont(par));
if (par.isLineSeparator(i - 1))
add -= singleWidth(par, i - 1);
// add the auto-hfill from label end to the body
if (body_pos && i == body_pos) {
int add = font_metrics::width(layout->labelsep, getLabelFont(par));
if (par.isLineSeparator(i - 1))
add -= singleWidth(par, i - 1);
add = std::max(add, labelEnd(pit) - x);
thiswidth += add;
}
x += thiswidth;
chunkwidth += thiswidth;
add = std::max(add, labelEnd(pit) - x);
thiswidth += add;
}
x += thiswidth;
chunkwidth += thiswidth;
// break before a character that will fall off
// the right of the row
if (x >= width) {
@ -2103,6 +2100,10 @@ int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
(body_pos > end || !par.isLineSeparator(body_pos - 1)))
body_pos = 0;
// Use font span to speed things up, see below
FontSpan font_span = par.fontSpan(row_pos);
LyXFont font = getFont(par, row_pos);
for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
pos_type pos = bidi.vis2log(vpos);
if (body_pos > 0 && pos == body_pos - 1) {
@ -2113,7 +2114,13 @@ int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
x -= singleWidth(par, body_pos - 1);
}
x += singleWidth(par, pos);
// Use font span to speed things up, see above
if (pos < font_span.first || pos > font_span.last) {
font_span = par.fontSpan(pos);
font = getFont(par, pos);
}
x += singleWidth(par, pos, par.getChar(pos), font);
if (hfillExpansion(par, row, pos))
x += (pos >= body_pos) ? m.hfill : m.label_hfill;

View File

@ -1520,7 +1520,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
default:
lyxerr << BOOST_CURRENT_FUNCTION
<< " Not DISPATCHED by LyXText" << endl;
<< ": Command " << cmd << " not DISPATCHED by LyXText" << endl;
cur.undispatched();
break;
}