Fix crash when row did rebreak while drawing (fix #351).

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4122 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Vigna 2002-05-03 09:22:07 +00:00
parent ec18ff30ad
commit 4564ce04e8
4 changed files with 42 additions and 22 deletions

View File

@ -1,3 +1,20 @@
2002-05-03 Juergen Vigna <jug@sad.it>
* screen.C (drawFromTo): recalculate the rowpointer if we had a
change in LyXText as we can not be sure it was not freed.
(drawOneRow): remove unused code.
* text.C (drawInset): redo the calculation of the need_break_row as
it could have a row which was already freed.
(draw): look at the return value of drawInset and return false if
it also returned false.
(paintRowText): look at the return value of draw and return false if
it also returned false.
* lyxtext.h: added bool return type to drawInset() and draw() so that
if we have a change in the row so that the rowbreak has to be redone
we abort drawing as it will be called again.
2002-05-02 Juergen Vigna <jug@sad.it>
* BufferView_pimpl.C (moveCursorUpdate): make repaint if we had

View File

@ -648,11 +648,11 @@ private:
/// draw a mark for foreign language, starting from orig_x
void drawForeignMark(DrawRowParams & p, float const orig_x, LyXFont const & orig_font);
/// draw an inset
void drawInset(DrawRowParams & p, lyx::pos_type const pos);
bool drawInset(DrawRowParams & p, lyx::pos_type const pos);
/// draw new line marker
void drawNewline(DrawRowParams & p, lyx::pos_type const pos);
/// draw text
void draw(DrawRowParams & p, lyx::pos_type & vpos);
bool draw(DrawRowParams & p, lyx::pos_type & vpos);
/// get the next breakpoint in a given paragraph
lyx::pos_type nextBreakPoint(BufferView *, Row const * row, int width) const;

View File

@ -135,6 +135,11 @@ void LyXScreen::drawFromTo(LyXText * text, BufferView * bv,
text->setCursor(bv, text->cursor.par(),
text->cursor.pos());
text->status(bv, st);
// we should be sure our row-pointer is still valid, so it's
// better to recompute it.
y_text = y + text->first_y;
row = text->getRowNearY(y_text);
y = y_text - text->first_y;
text->getVisibleRow(bv, y + y_offset,
x_offset, row, y + text->first_y);
}
@ -161,18 +166,7 @@ void LyXScreen::drawOneRow(LyXText * text, BufferView * bv, Row * row,
if (((y + row->height()) > 0) &&
((y - row->height()) <= static_cast<int>(owner.height()))) {
// ok there is something visible
#if 0
LyXText::text_status st = bv->text->status();
do {
bv->text->status(bv, st);
text->getVisibleRow(bv, y, x_offset, row,
y + text->first_y);
} while (!text->inset_owner &&
text->status() == LyXText::CHANGED_IN_DRAW);
bv->text->status(bv, st);
#else
text->getVisibleRow(bv, y, x_offset, row, y + text->first_y);
#endif
}
force_clear = false;
}

View File

@ -475,23 +475,25 @@ void LyXText::drawNewline(DrawRowParams & p, pos_type const pos)
}
void LyXText::drawInset(DrawRowParams & p, pos_type const pos)
bool LyXText::drawInset(DrawRowParams & p, pos_type const pos)
{
Inset * inset = p.row->par()->getInset(pos);
// FIXME: shouldn't happen
if (!inset) {
return;
return true;
}
LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
// we need this here as the row pointer may be illegal
// at a later time (Jug20020502)
Row * prev = p.row->previous();
inset->update(p.bv, font, false);
inset->draw(p.bv, font, p.yo + p.row->baseline(), p.x, p.cleared);
if (!need_break_row && !inset_owner
&& p.bv->text->status() == CHANGED_IN_DRAW) {
Row * prev = p.row->previous();
if (prev && prev->par() == p.row->par()) {
breakAgainOneRow(p.bv, prev);
if (prev->next() != p.row) {
@ -501,11 +503,15 @@ void LyXText::drawInset(DrawRowParams & p, pos_type const pos)
} else {
need_break_row = p.row;
}
} else if (!prev) {
need_break_row = firstrow;
} else {
need_break_row = p.row;
need_break_row = prev->next();
}
setCursor(p.bv, cursor.par(), cursor.pos());
return false;
}
return true;
}
@ -630,7 +636,7 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
}
void LyXText::draw(DrawRowParams & p, pos_type & vpos)
bool LyXText::draw(DrawRowParams & p, pos_type & vpos)
{
pos_type const pos = vis2log(vpos);
Paragraph * par = p.row->par();
@ -644,12 +650,13 @@ void LyXText::draw(DrawRowParams & p, pos_type & vpos)
if (IsNewlineChar(c)) {
++vpos;
drawNewline(p, pos);
return;
return true;
} else if (IsInsetChar(c)) {
drawInset(p, pos);
if (!drawInset(p, pos))
return false;
++vpos;
drawForeignMark(p, orig_x, orig_font);
return;
return true;
}
// usual characters, no insets
@ -681,6 +688,7 @@ void LyXText::draw(DrawRowParams & p, pos_type & vpos)
lyxerr << "No this shouldn't happen!\n";
#endif
#endif
return true;
}
@ -3662,7 +3670,8 @@ void LyXText::paintRowText(DrawRowParams & p)
p.x += p.separator;
++vpos;
} else {
draw(p, vpos);
if (!draw(p, vpos))
break;
}
}
}