The bug: http://bugzilla.lyx.org/show_bug.cgi?id=3875

The problem: On fullscreen redraw the metrics of all visible paragraphs are recreated and stored in the TextMetrics object. If the number of paragraphs on screen does not change everything is fine because the paragraph metrics cache is just updated. But if the number decreases it can happen that old paragraph metrics remain in the cache. If this happened because e.g. a paragraph was deleted, it's possible that the cached paragraph is longer than the one which is actually at the position now. Using the Row objects from the cached paragraphs then can trigger accesses to positions which would have been valid in the old paragraph, but go over the end of the paragraph which is there now.

Stefan

Index: src/BufferView.cpp
===================================================================
--- src/BufferView.cpp  (Revision 18837)
+++ src/BufferView.cpp  (Arbeitskopie)
@@ -1440,6 +1440,15 @@
                offset_ref_ = 0;
        }

+       if (!singlepar) {
+               // Clear out the position cache in case of full screen redraw,
+               coord_cache_.clear();
+       
+               // Clear out paragraph metrics to avoid having invalid metrics
+               // in the cache from paragraphs not relayouted below
+               tm.clear();
+       }
+
        // If the paragraph metrics has changed, we can not
        // use the singlepar optimisation.
        if (singlepar
@@ -1459,10 +1468,6 @@
        if (!singlepar)
                tm.redoParagraph(pit);

-       // Clear out the position cache in case of full screen redraw.
-       if (!singlepar)
-               coord_cache_.clear();
-
        int y0 = tm.parMetrics(pit).ascent() - offset_ref_;

        // Redo paragraphs above anchor if necessary.
Index: src/TextMetrics.h
===================================================================
--- src/TextMetrics.h   (Revision 18837)
+++ src/TextMetrics.h   (Arbeitskopie)
@@ -48,6 +48,8 @@
        /// \retval true if a full screen redraw is needed.
        /// \retval false if a single paragraph redraw is enough.
        bool redoParagraph(pit_type const pit);
+       /// Clear cache of paragraph metrics
+       void clear() { par_metrics_.clear(); }

        ///
        int ascent() const { return dim_.asc; }


Attachment: 3785.patch
Description: Binary data

Attachment: PGP.sig
Description: Signierter Teil der Nachricht

Reply via email to