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())
{}
++pos_;
if (pos_ > endspan_ || pos_ == bodypos_) {
font_ = text_.getFont(par_, pos_);
- endspan_ = par_.getFontSpan(pos_).second;
+ endspan_ = par_.fontSpan(pos_).last;
}
return *this;
}
arrays_.clear();
insets_.clear();
pars_.clear();
+ slices0_.clear();
+ slices1_.clear();
}
int x_, y_;
};
-
template <class T> class CoordCacheBase {
public:
void clear()
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_; }
/// 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.
}
-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;
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);
}
#include "support/types.h"
#include <string>
-#include <utility>
class Buffer;
class BufferParams;
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:
/**
* 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]; }
{
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
// 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))
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 = std::max(add, labelEnd(pit) - x);
- thiswidth += add;
- }
+ // 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);
- 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) {
(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) {
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;
default:
lyxerr << BOOST_CURRENT_FUNCTION
- << " Not DISPATCHED by LyXText" << endl;
+ << ": Command " << cmd << " not DISPATCHED by LyXText" << endl;
cur.undispatched();
break;
}