Hi, attached patch fixes the infinite loop with the document attached to comment #3 in https://bugs.kde.org/show_bug.cgi?id=260219 .
The idea is to not include the previous and next root-areas and mark them dirty if charsAdded and charsRemoved ==0 what means no characters where changed. In such a case we can assume that the change is related to the current root-area only.
diff --git a/libs/textlayout/KoTextDocumentLayout.cpp b/libs/textlayout/KoTextDocumentLayout.cpp index 34523f1..c4e8ccd 100644 --- a/libs/textlayout/KoTextDocumentLayout.cpp +++ b/libs/textlayout/KoTextDocumentLayout.cpp @@ -251,18 +251,29 @@ void KoTextDocumentLayout::documentChanged(int position, int charsRemoved, int c from = block.position() + block.length(); } - // Mark the to the position corresponding root-areas as dirty. We determinate the range of the root-areas - // the added and removed chars span. Additionaly the previous and following root-area of that range are - // selected too cause they can also be affect by changes done to the range. All that root-areas then marked - // dirty. If there is no root-area for the position then we don't need to mark anything dirty but still - // need to go on to force a scheduled relayout. + // Mark the to the position corresponding root-areas as dirty. If there is no root-area for the position then we + // don't need to mark anything dirty but still need to go on to force a scheduled relayout. if (!d->rootAreaList.isEmpty()) { KoTextLayoutRootArea *fromArea = rootAreaForPosition(position); - KoTextLayoutRootArea *toArea = fromArea ? rootAreaForPosition(position + qMax(charsRemoved, charsAdded)) : 0; - int startIndex = qMax(0, fromArea ? d->rootAreaList.indexOf(fromArea) - 1 : 0); - int endIndex = qMax(startIndex, qMin(d->rootAreaList.count() - 1, ((toArea && toArea != fromArea) ? d->rootAreaList.indexOf(toArea) : startIndex) + 1)); - for(int i = startIndex; i <= endIndex; ++i) { - d->rootAreaList[i]->setDirty(); + int startIndex = fromArea ? qMax(0, d->rootAreaList.indexOf(fromArea)) : 0; + if (startIndex >= 0) { + int endIndex = startIndex; + if (charsRemoved != 0 || charsAdded != 0) { + // If any characters got removed or added make sure to also catch other root-areas that may be + // affected by this change. + KoTextLayoutRootArea *toArea = fromArea ? rootAreaForPosition(position + qMax(charsRemoved, charsAdded)) : 0; + endIndex = (toArea && toArea != fromArea) ? qMax(startIndex, d->rootAreaList.indexOf(toArea)) : startIndex; + // The previous and following root-area of that range are selected too cause they can also be affect by + // changes done to the range. + if (startIndex >= 1) + --startIndex; + if (endIndex + 1 < d->rootAreaList.count()) + ++endIndex; + } + // Mark all selected root-areas as dirty so they are relayouted. + for(int i = startIndex; i <= endIndex; ++i) { + d->rootAreaList[i]->setDirty(); + } } }
_______________________________________________ calligra-devel mailing list calligra-devel@kde.org https://mail.kde.org/mailman/listinfo/calligra-devel