Stefan Schimanski wrote:
Another possibility of course (which I proposed somewhere in the other
thread about the backspace case of Dov) is so redo the metrics of the
current paragraph before setting the current font again. But then I
guess they are computed twice, also during the paragraph update later.
Stefan
Am 02.06.2007 um 18:13 schrieb Stefan Schimanski:
Hi!
In http://bugzilla.lyx.org/show_bug.cgi?id=3790 a bug is reported that
LyX crashes when deleting a display math at the end of a paragraph. In
fact the same bug can also be triggered by backspace, enter to rebreak
the paragraph and probably many more ways.
The reason is that Text::setCursor (which is often called after some
user action on the text to update the cursor to the new position)
tries to set the current font by Text::setCurrentFont. For this the
correct paragraph metrics are needed and the RTL/LTR status of the
char behind or in front of the cursor.
The latter triggers a Bidi::computeTables call which goes through the
current line of the paragraph and sets the RTL value correctly. But
for that is depends on the Row object which is only valid if the
paragraph metrics are valid.
The crashes which can easily be triggered with RC1, come from the
Bidi::computeTables which uses that Row::endpos() information to know
the end of the row. But after actions like backspace this value is
wrong, hence invalid accesses are the consequence.
The easy fix for all that is this one:
Index: src/Bidi.cpp
===================================================================
--- src/Bidi.cpp (Revision 18631)
+++ src/Bidi.cpp (Arbeitskopie)
@@ -66,8 +66,11 @@
}
start_ = row.pos();
- end_ = row.endpos() - 1;
-
+
+ // possibly the row metrics are outdated and the endpos() was
computed
+ // before the paragraph was changed (e.g. by backspace)
+ end_ = std::min(par.size(), row.endpos()) - 1;
+
if (start_ > end_) {
start_ = -1;
return;
The paragraph knows the right size all the time because it is what the
action handlers (e.g. for backspace) modify.
In fact a clean solution would look differently IMO. Text::setCursor
should not update the font at all, but trigger some kind of update
(via the the Cursor's UpdateFlags) which then, after the new paragraph
metrics are calculated, sets the font at the cursors position. Not
sure though if this is something for intra-RC1-RC2 patches. Any opinions?
The crashes I encountered up to now can all be fixed the upper patch.
So I suggest to put that in for now.
Stefan
Hi!
I think your second solution (deferring the setting of the font to until
after the metrics are calculated) sounds best.
If that's too risky / too hard until after the 1.5.0 release, then I
prefer your previous solution, of forcing a recalculation of the metrics
before calling computeTables --- as you pointed out to me, even though
we'll be computing the metrics twice that way, it's probably negligible
next to the redrawing...
The suggestion of modifying computeTables itself seems a little hackish:
so why are you trusting the row for the start_ position? Maybe that's
not correct, either? Also, there are situations which I'm not sure that
the hack would solve: when we move from one row to the previous one ---
then obviously the paragraph size is not an issue, because we're not on
the last row of the paragraph --- but the row metrics are still
incorrect. (When we first noticed this problem a few weeks ago, I solved
it by adding the call to computeTables from within setCurrentFont, which
is now causing the problem; this could probably be removed if you redo
the metrics?).
Dov