summaryrefslogtreecommitdiffstats
path: root/tests/manual/qglyphruns
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/qglyphruns')
-rw-r--r--tests/manual/qglyphruns/CMakeLists.txt17
-rw-r--r--tests/manual/qglyphruns/controller.cpp57
-rw-r--r--tests/manual/qglyphruns/controller.h29
-rw-r--r--tests/manual/qglyphruns/controller.ui200
-rw-r--r--tests/manual/qglyphruns/glyphruninspector.cpp48
-rw-r--r--tests/manual/qglyphruns/glyphruninspector.h31
-rw-r--r--tests/manual/qglyphruns/main.cpp18
-rw-r--r--tests/manual/qglyphruns/singleglyphrun.cpp73
-rw-r--r--tests/manual/qglyphruns/singleglyphrun.h30
-rw-r--r--tests/manual/qglyphruns/singleglyphrun.ui61
-rw-r--r--tests/manual/qglyphruns/view.cpp70
-rw-r--r--tests/manual/qglyphruns/view.h42
12 files changed, 676 insertions, 0 deletions
diff --git a/tests/manual/qglyphruns/CMakeLists.txt b/tests/manual/qglyphruns/CMakeLists.txt
new file mode 100644
index 0000000000..4af9c3e241
--- /dev/null
+++ b/tests/manual/qglyphruns/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_manual_test(qglyphrun
+ GUI
+ SOURCES
+ main.cpp
+ controller.h controller.cpp controller.ui
+ view.h view.cpp
+ glyphruninspector.h glyphruninspector.cpp
+ singleglyphrun.h singleglyphrun.cpp singleglyphrun.ui
+ LIBRARIES
+ Qt::Gui
+ Qt::Widgets
+ ENABLE_AUTOGEN_TOOLS
+ uic
+)
diff --git a/tests/manual/qglyphruns/controller.cpp b/tests/manual/qglyphruns/controller.cpp
new file mode 100644
index 0000000000..0037d11b5b
--- /dev/null
+++ b/tests/manual/qglyphruns/controller.cpp
@@ -0,0 +1,57 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "controller.h"
+#include "ui_controller.h"
+
+Controller::Controller(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::Controller)
+{
+ ui->setupUi(this);
+
+ connect(ui->cbWrap, &QCheckBox::toggled, this, &Controller::updateViews);
+ connect(ui->gbRange, &QGroupBox::toggled, this, &Controller::updateViews);
+ connect(ui->teSourceString, &QPlainTextEdit::textChanged, this, &Controller::updateViews);
+ connect(ui->hsLineWidth, &QSlider::valueChanged, this, &Controller::updateViews);
+ connect(ui->inspector, &GlyphRunInspector::updateBounds, ui->view, &View::setVisualizedBounds);
+ connect(ui->sbFrom, &QSpinBox::valueChanged, this, &Controller::updateViews);
+ connect(ui->sbTo, &QSpinBox::valueChanged, this, &Controller::updateViews);
+ connect(ui->teSourceString, &QPlainTextEdit::selectionChanged, this, &Controller::updateRange);
+ connect(ui->fcbFont, &QFontComboBox::currentFontChanged, this, &Controller::updateViews);
+}
+
+Controller::~Controller()
+{
+ delete ui;
+}
+
+void Controller::updateRange()
+{
+ if (ui->gbRange->isChecked()) {
+ QTextCursor cursor = ui->teSourceString->textCursor();
+ if (cursor.hasSelection()) {
+ ui->sbFrom->setValue(cursor.selectionStart());
+ ui->sbTo->setValue(cursor.selectionEnd() - 1);
+
+ updateViews();
+ }
+ }
+}
+
+void Controller::updateViews()
+{
+ QString s = ui->teSourceString->toPlainText();
+ ui->sbFrom->setMaximum(s.length());
+ ui->sbTo->setMaximum(s.length());
+
+ s.replace('\n', QChar::LineSeparator);
+ ui->view->updateLayout(s,
+ qreal(ui->hsLineWidth->value()) * ui->hsLineWidth->width() / 100.0f,
+ ui->cbWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::ManualWrap,
+ ui->fcbFont->currentFont());
+
+ int start = ui->gbRange->isChecked() ? ui->sbFrom->value() : -1;
+ int length = ui->gbRange->isChecked() ? ui->sbTo->value() - start + 1 : -1;
+ ui->inspector->updateLayout(ui->view->layout(), start, length);
+}
diff --git a/tests/manual/qglyphruns/controller.h b/tests/manual/qglyphruns/controller.h
new file mode 100644
index 0000000000..75289165f8
--- /dev/null
+++ b/tests/manual/qglyphruns/controller.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef CONTROLLER_H
+#define CONTROLLER_H
+
+#include <QWidget>
+
+namespace Ui {
+class Controller;
+}
+
+class Controller : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Controller(QWidget *parent = nullptr);
+ ~Controller();
+
+private slots:
+ void updateViews();
+ void updateRange();
+
+private:
+ Ui::Controller *ui;
+};
+
+#endif // CONTROLLER_H
diff --git a/tests/manual/qglyphruns/controller.ui b/tests/manual/qglyphruns/controller.ui
new file mode 100644
index 0000000000..903135a281
--- /dev/null
+++ b/tests/manual/qglyphruns/controller.ui
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Controller</class>
+ <widget class="QWidget" name="Controller">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>549</width>
+ <height>419</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Source string:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="teSourceString"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="cbWrap">
+ <property name="text">
+ <string>Wrap</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFontComboBox" name="fcbFont"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="gbRange">
+ <property name="title">
+ <string>Range</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>From</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbFrom"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>To</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbTo"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Display</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="View" name="view" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QSlider" name="hsLineWidth">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="GlyphRunInspector" name="inspector" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbQuit">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>View</class>
+ <extends>QWidget</extends>
+ <header>view.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>GlyphRunInspector</class>
+ <extends>QWidget</extends>
+ <header>glyphruninspector.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pbQuit</sender>
+ <signal>clicked()</signal>
+ <receiver>Controller</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>517</x>
+ <y>398</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>35</x>
+ <y>-16</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tests/manual/qglyphruns/glyphruninspector.cpp b/tests/manual/qglyphruns/glyphruninspector.cpp
new file mode 100644
index 0000000000..0e35a1f94b
--- /dev/null
+++ b/tests/manual/qglyphruns/glyphruninspector.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "glyphruninspector.h"
+#include "singleglyphrun.h"
+
+#include <QTextLayout>
+#include <QtWidgets>
+
+GlyphRunInspector::GlyphRunInspector(QWidget *parent)
+ : QWidget{parent}
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+
+ m_tabWidget = new QTabWidget;
+ layout->addWidget(m_tabWidget);
+
+ connect(m_tabWidget,
+ &QTabWidget::currentChanged,
+ this,
+ &GlyphRunInspector::updateVisualizationForTab);
+}
+
+void GlyphRunInspector::updateVisualizationForTab()
+{
+ int currentTab = m_tabWidget->currentIndex();
+ SingleGlyphRun *gr = currentTab >= 0 && currentTab < m_content.size() ? m_content.at(currentTab) : nullptr;
+ if (gr != nullptr)
+ emit updateBounds(gr->bounds());
+}
+
+void GlyphRunInspector::updateLayout(QTextLayout *layout, int start, int length)
+{
+ QList<QGlyphRun> glyphRuns = layout->glyphRuns(start, length, QTextLayout::RetrieveAll);
+
+ m_tabWidget->clear();
+ qDeleteAll(m_content);
+ m_content.clear();
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ SingleGlyphRun *w = new SingleGlyphRun(m_tabWidget);
+ w->updateGlyphRun(glyphRuns.at(i));
+
+ m_tabWidget->addTab(w, QStringLiteral("%1").arg(glyphRuns.at(i).rawFont().familyName()));
+ m_content.append(w);
+ }
+
+ updateVisualizationForTab();
+}
diff --git a/tests/manual/qglyphruns/glyphruninspector.h b/tests/manual/qglyphruns/glyphruninspector.h
new file mode 100644
index 0000000000..d2aa6033db
--- /dev/null
+++ b/tests/manual/qglyphruns/glyphruninspector.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef GLYPHRUNINSPECTOR_H
+#define GLYPHRUNINSPECTOR_H
+
+#include <QWidget>
+
+class QTextLayout;
+class QTabWidget;
+class SingleGlyphRun;
+class GlyphRunInspector : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit GlyphRunInspector(QWidget *parent = nullptr);
+
+ void updateLayout(QTextLayout *layout, int start, int length);
+
+private slots:
+ void updateVisualizationForTab();
+
+signals:
+ void updateBounds(const QRegion &region);
+
+private:
+ QTabWidget *m_tabWidget;
+ QList<SingleGlyphRun *> m_content;
+};
+
+#endif // GLYPHRUNINSPECTOR_H
diff --git a/tests/manual/qglyphruns/main.cpp b/tests/manual/qglyphruns/main.cpp
new file mode 100644
index 0000000000..0f192e051f
--- /dev/null
+++ b/tests/manual/qglyphruns/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "controller.h"
+
+#include <QtWidgets>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ Controller controller;
+ controller.showMaximized();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/qglyphruns/singleglyphrun.cpp b/tests/manual/qglyphruns/singleglyphrun.cpp
new file mode 100644
index 0000000000..9a5bd3e139
--- /dev/null
+++ b/tests/manual/qglyphruns/singleglyphrun.cpp
@@ -0,0 +1,73 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "singleglyphrun.h"
+#include "ui_singleglyphrun.h"
+
+SingleGlyphRun::SingleGlyphRun(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::SingleGlyphRun)
+{
+ ui->setupUi(this);
+}
+
+SingleGlyphRun::~SingleGlyphRun()
+{
+ delete ui;
+}
+
+void SingleGlyphRun::updateGlyphRun(const QGlyphRun &glyphRun)
+{
+ m_bounds = QRegion();
+
+ QList<quint32> glyphIndexes = glyphRun.glyphIndexes();
+ QList<qsizetype> stringIndexes = glyphRun.stringIndexes();
+ QList<QPointF> glyphPositions = glyphRun.positions();
+
+ ui->twGlyphRun->clearContents();
+ ui->twGlyphRun->setRowCount(glyphIndexes.size());
+
+ for (int i = 0; i < glyphIndexes.size(); ++i) {
+ {
+ QTableWidgetItem *glyphIndex = new QTableWidgetItem(QString::number(glyphIndexes.at(i)));
+ ui->twGlyphRun->setItem(i, 0, glyphIndex);
+ }
+
+ {
+ QPointF position = glyphPositions.at(i);
+ QTableWidgetItem *glyphPosition = new QTableWidgetItem(QStringLiteral("(%1, %2)")
+ .arg(position.x())
+ .arg(position.y()));
+ ui->twGlyphRun->setItem(i, 1, glyphPosition);
+ }
+
+ {
+ QTableWidgetItem *stringIndex = new QTableWidgetItem(QString::number(stringIndexes.at(i)));
+ ui->twGlyphRun->setItem(i, 2, stringIndex);
+ }
+
+ QChar c = glyphRun.sourceString().at(stringIndexes.at(i));
+
+ {
+ QTableWidgetItem *unicode = new QTableWidgetItem(QString::number(c.unicode(), 16));
+ ui->twGlyphRun->setItem(i, 3, unicode);
+ }
+
+ {
+ QTableWidgetItem *character = new QTableWidgetItem(c);
+ ui->twGlyphRun->setItem(i, 4, character);
+ }
+
+ {
+ QImage image = glyphRun.rawFont().alphaMapForGlyph(glyphIndexes.at(i));
+
+ QTableWidgetItem *glyphImage = new QTableWidgetItem(QIcon(QPixmap::fromImage(image)), QString{});
+ ui->twGlyphRun->setItem(i, 5, glyphImage);
+ }
+
+ QRectF brect = glyphRun.rawFont().boundingRect(glyphIndexes.at(i));
+ brect.adjust(glyphPositions.at(i).x(), glyphPositions.at(i).y(),
+ glyphPositions.at(i).x(), glyphPositions.at(i).y());
+ m_bounds += brect.toAlignedRect();
+ }
+}
diff --git a/tests/manual/qglyphruns/singleglyphrun.h b/tests/manual/qglyphruns/singleglyphrun.h
new file mode 100644
index 0000000000..138d820ad4
--- /dev/null
+++ b/tests/manual/qglyphruns/singleglyphrun.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef SINGLEGLYPHRUN_H
+#define SINGLEGLYPHRUN_H
+
+#include <QWidget>
+#include <QGlyphRun>
+
+namespace Ui {
+class SingleGlyphRun;
+}
+
+class SingleGlyphRun : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SingleGlyphRun(QWidget *parent = nullptr);
+ ~SingleGlyphRun();
+
+ void updateGlyphRun(const QGlyphRun &glyphRun);
+ QRegion bounds() const { return m_bounds; }
+
+private:
+ Ui::SingleGlyphRun *ui;
+ QRegion m_bounds;
+};
+
+#endif // SINGLEGLYPHRUN_H
diff --git a/tests/manual/qglyphruns/singleglyphrun.ui b/tests/manual/qglyphruns/singleglyphrun.ui
new file mode 100644
index 0000000000..e2c8860de0
--- /dev/null
+++ b/tests/manual/qglyphruns/singleglyphrun.ui
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SingleGlyphRun</class>
+ <widget class="QWidget" name="SingleGlyphRun">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>599</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QTableWidget" name="twGlyphRun">
+ <column>
+ <property name="text">
+ <string>Glyph index</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Glyph position</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>String index</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Unicode</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Character</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Font glyph</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/qglyphruns/view.cpp b/tests/manual/qglyphruns/view.cpp
new file mode 100644
index 0000000000..0e7d6dd478
--- /dev/null
+++ b/tests/manual/qglyphruns/view.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "view.h"
+#include <QTextLayout>
+#include <QPainter>
+
+View::View(QWidget *parent)
+ : QWidget{parent}
+{
+ setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum));
+}
+
+View::~View()
+{
+ delete m_layout;
+}
+
+void View::updateLayout(const QString &sourceString,
+ float width,
+ QTextOption::WrapMode mode,
+ const QFont &font)
+{
+ if (m_layout == nullptr)
+ m_layout = new QTextLayout;
+
+ m_layout->setText(sourceString);
+ QTextOption option;
+ option.setWrapMode(mode);
+ m_layout->setTextOption(option);
+ m_layout->setFont(font);
+ m_layout->beginLayout();
+ float y = 0.0f;
+ forever {
+ QTextLine line = m_layout->createLine();
+ if (!line.isValid())
+ break;
+
+ line.setLineWidth(width);
+ line.setPosition(QPointF(0, y));
+ y += line.height();
+ }
+ m_layout->endLayout();
+
+ update();
+ updateGeometry();
+}
+
+QSize View::sizeHint() const
+{
+ if (m_layout != nullptr)
+ return m_layout->boundingRect().size().toSize();
+ else
+ return QSize(100, 100);
+}
+
+void View::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ if (m_layout != nullptr)
+ m_layout->draw(&p, QPointF(0, 0));
+ if (!m_bounds.isEmpty()) {
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::yellow);
+ p.setOpacity(0.25);
+ for (const QRect &r : m_bounds) {
+ p.drawRect(r);
+ }
+ }
+}
diff --git a/tests/manual/qglyphruns/view.h b/tests/manual/qglyphruns/view.h
new file mode 100644
index 0000000000..a8c3c1aed9
--- /dev/null
+++ b/tests/manual/qglyphruns/view.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <QWidget>
+#include <QTextOption>
+
+class QTextLayout;
+class View : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit View(QWidget *parent = nullptr);
+ ~View() override;
+
+ void updateLayout(const QString &sourceString,
+ float width,
+ QTextOption::WrapMode mode,
+ const QFont &font);
+
+ QSize sizeHint() const override;
+
+ QTextLayout *layout() const { return m_layout; }
+
+public slots:
+ void setVisualizedBounds(const QRegion &region)
+ {
+ m_bounds = region;
+ update();
+ }
+
+protected:
+ void paintEvent(QPaintEvent *e) override;
+
+private:
+ QTextLayout *m_layout = nullptr;
+ QRegion m_bounds;
+};
+
+#endif // VIEW_H