@@ -76,11 +76,11 @@ class LayoutBlockData : public QTextBlockUserData
7676public:
7777 static constexpr BlockDataKind DATA_KIND = BlockDataKind::LAYOUT;
7878
79- LayoutBlockData () : textHash (qHash(QStringView())) {}
79+ LayoutBlockData () : contentHash (qHash(QStringView())) {}
8080
8181 std::unique_ptr<QTextLayout> displayLayout;
8282 QList<ushort> displayOffsets;
83- size_t textHash ;
83+ size_t contentHash ;
8484};
8585
8686static int adjustPosToDisplay (const QList<ushort>& displayOffsets, int pos)
@@ -372,15 +372,37 @@ void EditorLayout::doDocumentLayout(const QTextBlock& startBlock, const QTextBlo
372372 Q_EMIT update ();
373373}
374374
375+ static size_t hashBlockContent (const QTextBlock& block, const QString& blockText)
376+ {
377+ size_t hash = qHash (blockText);
378+
379+ const QList<QTextLayout::FormatRange> formats = block.layout ()->formats ();
380+ for (const QTextLayout::FormatRange& r : formats) {
381+ // We need to hash the text formats too, to recognize theme changes and
382+ // things stopping being spelling errors due to dictionary changes. The
383+ // problem is that QTextFormat doesn't provide a hash function. Doing
384+ // that generically for all possible properties is rather grueling,
385+ // let's just pick the minimal properties that will act as proxy for the
386+ // events listed above.
387+ hash = qHashMulti (hash,
388+ r.start ,
389+ r.length ,
390+ r.format .foreground ().color ().rgb (),
391+ r.format .underlineColor ().rgb ());
392+ }
393+
394+ return hash;
395+ }
396+
375397static void buildDisplayLayout (const QTextBlock& block, QString blockText, LayoutBlockData* blockData)
376398{
377- size_t newHash = qHash ( blockText);
399+ size_t newHash = hashBlockContent (block, blockText);
378400
379401 // Calculating a display layout is expensive, only do it if content actually changed
380- if (newHash == blockData->textHash ) {
402+ if (newHash == blockData->contentHash ) {
381403 return ;
382404 }
383- blockData->textHash = newHash;
405+ blockData->contentHash = newHash;
384406
385407 IsolatesBlockData* isolateData = BlockData::get<IsolatesBlockData>(block);
386408 if (isolateData == nullptr || isolateData->isolates ().isEmpty ()) {
@@ -693,16 +715,6 @@ int EditorLayout::getLineEdgePosition(int pos, QTextLine::Edge edge) const
693715 return block.position () + origLayoutPos;
694716}
695717
696- void EditorLayout::invalidateAllDisplayLayouts ()
697- {
698- for (QTextBlock block = document ()->begin (); block.isValid (); block = block.next ()) {
699- LayoutBlockData* layoutData = BlockData::get<LayoutBlockData>(block);
700- if (layoutData) {
701- layoutData->displayLayout .reset ();
702- }
703- }
704- }
705-
706718void EditorLayout::recalculateDocumentSize ()
707719{
708720 // TODO: This way (recalculating from scratch after every change) ensures
0 commit comments