From 779479c5474e080a857b2d80bdc86b9cab6531a0 Mon Sep 17 00:00:00 2001
From: Jaroslaw Staniek <staniek@kde.org>
Date: Fri, 1 Nov 2019 19:54:00 +0100
Subject: [PATCH] Fix insane delay in report items creation

Summary:
Fix insane delay in report items creation by not instantiating hi-resolution QPrinter object for each item.

To be honest I am not understanding the whole word-wrapping algorithm used here.

Test Plan:
Approach 1: Run KEXI and create report with large number of pages. Use at
least one text element.
Before the fix there's noticeable O(N) delay.

Approach 2: Also if we enter static value for the text item the kreportexample
app, there is noticeable delay on each key press before this fix.

Expected: all is smooth after the fix.

Reviewers: piggz

Reviewed By: piggz

Subscribers: Kexi-Devel-list

Tags: #kreport

Differential Revision: https://phabricator.kde.org/D25108
---
 src/CMakeLists.txt                 |  2 ++
 src/common/KReportUtils_p.cpp      | 14 +++++++++++---
 src/common/KReportUtils_p.h        | 12 +++++++++++-
 src/items/text/KReportItemText.cpp | 11 ++++++-----
 4 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e15d5ca6..1cf0b389 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -198,6 +198,8 @@ target_link_libraries(KReportUtilsPrivate
         Qt5::Widgets
         KF5::ConfigGui
         KF5::WidgetsAddons
+    PRIVATE
+        Qt5::PrintSupport
     )
 
 ecm_setup_version(${PROJECT_VERSION}
diff --git a/src/common/KReportUtils_p.cpp b/src/common/KReportUtils_p.cpp
index 5ac288bb..0fd90c2f 100644
--- a/src/common/KReportUtils_p.cpp
+++ b/src/common/KReportUtils_p.cpp
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2015-2016 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2015-2019 Jarosław Staniek <staniek@kde.org>
    Copyright (C) 2016 Adam Pigg <adam@piggz.co.uk>
 
    This library is free software; you can redistribute it and/or
@@ -26,13 +26,14 @@
 #include <KMessageBox>
 
 #include <QApplication>
+#include <QDebug>
 #include <QDir>
 #include <QFileInfo>
+#include <QGlobalStatic>
+#include <QPrinter>
 #include <QRegularExpression>
 #include <QResource>
 #include <QStandardPaths>
-#include <QDebug>
-#include <QGlobalStatic>
 
 #ifdef Q_WS_X11
 #include <QX11Info>
@@ -329,6 +330,13 @@ int dpiY()
     return s_instance->m_dpiY;
 }
 
+Q_GLOBAL_STATIC_WITH_ARGS(QPrinter, s_printerInstance, (QPrinter::HighResolution))
+
+QPrinter* highResolutionPrinter()
+{
+    return s_printerInstance;
+}
+
 PageLayout::PageLayout() : QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0,0,0,0))
 {
 }
diff --git a/src/common/KReportUtils_p.h b/src/common/KReportUtils_p.h
index 1d223f6e..9e4b111b 100644
--- a/src/common/KReportUtils_p.h
+++ b/src/common/KReportUtils_p.h
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2015-2016 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2015-2019 Jarosław Staniek <staniek@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -26,6 +26,8 @@
 #include <QRect>
 #include <QStandardPaths>
 
+class QPrinter;
+
 const bool DEFAULT_SHOW_GRID = true;
 const bool DEFAULT_SNAP_TO_GRID = true;
 const int DEFAULT_GRID_DIVISIONS = 4;
@@ -173,6 +175,14 @@ int dpiX();
 
 int dpiY();
 
+/*!
+ * Returns a high-resolution printer
+ *
+ * The QPrinter(QPrinter::HighResolution)) instance is created on first call.
+ * The global printer helps to optimize access to QPrinter when report items need it.
+ */
+QPrinter* highResolutionPrinter();
+
 //! This class is wrapper that fixes a critical QTBUG-47551 bug in default constructor of QPageLayout
 //! Default constructor of QPageLayout does not initialize units.
 //! https://bugreports.qt.io/browse/QTBUG-47551
diff --git a/src/items/text/KReportItemText.cpp b/src/items/text/KReportItemText.cpp
index 29f63998..e05088fa 100644
--- a/src/items/text/KReportItemText.cpp
+++ b/src/items/text/KReportItemText.cpp
@@ -1,5 +1,6 @@
 /* This file is part of the KDE project
  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
+ * Copyright (C) 2019 Jarosław Staniek <staniek@kde.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,8 +18,9 @@
 
 #include "KReportItemText.h"
 #include "KReportRenderObjects.h"
-#include "kreportplugin_debug.h"
 #include "KReportUtils.h"
+#include "KReportUtils_p.h"
+#include "kreportplugin_debug.h"
 
 #include <KPropertyListData>
 #include <KPropertySet>
@@ -217,11 +219,10 @@ int KReportItemText::renderSimpleData(OROPage *page, OROSection *section, const
         int pos = 0;
         QChar separator;
         QRegularExpression re(QLatin1String("\\s"));
-        QPrinter prnt(QPrinter::HighResolution);
-        QFontMetricsF fm(font(), &prnt);
+        const QFontMetricsF fm(font(), KReportPrivate::highResolutionPrinter());
 
-        // int   intRectWidth    = (int)(trf.width() * prnt.resolution()) - 10;
-        int     intRectWidth    = (int)((size().width() / 72) * prnt.resolution());
+        const int intRectWidth
+            = (int)((size().width() / 72) * KReportPrivate::highResolutionPrinter()->resolution());
         int     intLineCounter  = 0;
         qreal   intBaseTop      = trf.top();
         qreal   intRectHeight   = trf.height();
-- 
GitLab

