+2003-04-11 Alfredo Braunstein <abraunst@libero.it>
+
+ * lyxrow.[Ch]: add a cached y position to a Row and Row::y()
+ methods to access it.
+ * lyxtext.h:
+ * text.C: Added updateRowPositions to compute all row positions.
+ Make top_y and getRowNearY() to use the cached y position
+
2003-04-11 John Levon <levon@movementarian.org>
* text.C (rowBreakPoint): reintroduce the labelEnd
+2003-04-11 Alfredo Braunstein <abraunst@libero.it>
+
+ * screen.C (update): add calls to updateRowPositions() before
+ drawOneRow and drawFromTo.
+
2003-04-10 John Levon <levon@movementarian.org>
* Toolbar.h:
switch (text->refreshStatus()) {
case LyXText::REFRESH_AREA:
{
+ text->updateRowPositions();
int const y = max(int(text->refresh_y - text->top_y()), 0);
drawFromTo(text, &bv, y, vheight, yo, xo);
expose(0, y, vwidth, vheight - y);
break;
case LyXText::REFRESH_ROW:
{
+ text->updateRowPositions();
// ok I will update the current cursor row
drawOneRow(text, &bv, text->refresh_row, text->refresh_y,
yo, xo);
{
lyxerr[Debug::GUI] << "screen: drawFromTo " << y1 << '-' << y2 << endl;
- int y_text = text->top_y() + y1;
-
- // get the first needed row
- RowList::iterator row = text->getRowNearY(y_text);
- RowList::iterator end = text->rows().end();
-
- // y_text is now the real beginning of the row
-
- int y = y_text - text->top_y();
+ int const topy = text->top_y();
+ int y_text = topy + y1;
+ RowList::iterator rit = text->getRowNearY(y_text);
+ int y = y_text - topy;
// y1 is now the real beginning of row on the screen
- while (row != end && y < y2) {
- RowPainter rp(*bv, *text, row);
- rp.paint(y + yo, xo, y + text->top_y());
- y += row->height();
- ++row;
+ RowList::iterator const rend = text->rows().end();
+ while (rit != rend && y < y2) {
+ RowPainter rp(*bv, *text, rit);
+ rp.paint(y + yo, xo, y + topy);
+ y += rit->height();
+ ++rit;
}
// maybe we have to clear the screen at the bottom
using std::min;
Row::Row()
- : pos_(0), fill_(0), height_(0), width_(0),
+ : pos_(0), fill_(0), height_(0), width_(0), y_(0),
ascent_of_text_(0), baseline_(0)
{}
Row::Row(ParagraphList::iterator pit, pos_type po)
- : pit_(pit), pos_(po), fill_(0), height_(0), width_(0),
+ : pit_(pit), pos_(po), fill_(0), height_(0), width_(0), y_(0),
ascent_of_text_(0), baseline_(0)
{}
+void Row::y(unsigned int newy)
+{
+ y_ = newy;
+}
+
+
+unsigned int Row::y() const
+{
+ return y_;
+}
+
+
ParagraphList::iterator Row::par()
{
return pit_;
unsigned int baseline() const;
/// return true if this row is the start of a paragraph
bool isParStart() const;
+ /// return the cached y position
+ unsigned int y() const;
+ /// cache the y position
+ void y(unsigned int newy);
private:
///
ParagraphList::iterator pit_;
unsigned short height_;
///
unsigned int width_;
+ /// cached y position
+ unsigned int y_;
/// ascent from baseline including prelude space
unsigned short ascent_of_text_;
/// the top of the real text in the row
*/
int anchor_row_offset_;
public:
+ /// update all cached row positions
+ void updateRowPositions();
/// get the y coord. of the top of the screen (relative to doc start)
int top_y() const;
/// set the y coord. of the top of the screen (relative to doc start)
}
-int LyXText::top_y() const
+void LyXText::updateRowPositions()
{
- if (anchor_row_ == rowlist_.end())
- return 0;
-
- int y = 0;
-
- RowList::iterator rit = rowlist_.begin();
- RowList::iterator end = rowlist_.end();
- for (; rit != end && rit != anchor_row_; ++rit) {
+ RowList::iterator rit = rows().begin();
+ RowList::iterator rend = rows().end();
+ for (int y = 0; rit != rend ; ++rit) {
+ rit->y(y);
y += rit->height();
}
- return y + anchor_row_offset_;
+}
+
+
+int LyXText::top_y() const
+{
+ if (isInInset() || anchor_row_ == rowlist_.end() )
+ return 0;
+ return anchor_row_->y() + anchor_row_offset_;
}
void LyXText::top_y(int newy)
{
- if (rows().empty())
+ if (rows().empty() || isInInset())
return;
lyxerr[Debug::GUI] << "setting top y = " << newy << endl;
RowList::iterator LyXText::getRowNearY(int & y) const
{
- // If possible we should optimize this method. (Lgb)
- int tmpy = 0;
- RowList::iterator rit = rowlist_.begin();
- RowList::iterator end = rowlist_.end();
+ RowList::iterator rit = anchor_row_;
+ RowList::iterator const beg = rows().begin();
+ RowList::iterator const end = rows().end();
- while (rit != end &&
- boost::next(rit) != end &&
- tmpy + rit->height() <= y) {
- tmpy += rit->height();
- ++rit;
+ if (rows().empty()) {
+ y = 0;
+ return end;
+ }
+ if (rit == end)
+ rit = beg;
+
+ int tmpy = rit->y();
+
+ if (tmpy <= y) {
+ while (rit != end && tmpy <= y) {
+ tmpy += rit->height();
+ ++rit;
+ }
+ if (rit != beg) {
+ --rit;
+ tmpy -= rit->height();
+ }
+ } else {
+ while (rit != beg && tmpy > y) {
+ --rit;
+ tmpy -= rit->height();
+ }
+ }
+ if (tmpy < 0 || rit == end) {
+ tmpy = 0;
+ rit = beg;
}
- // return the real y
+ // return the rel y
y = tmpy;
return rit;
if (anchor_row_ == rit) {
if (rit != rows().begin()) {
anchor_row_ = boost::prior(rit);
- anchor_row_offset_ += boost::prior(rit)->height();
+ anchor_row_offset_ += anchor_row_->height();
} else {
anchor_row_ = boost::next(rit);
anchor_row_offset_ -= rit->height();