1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32#include <qcoreapplication.h>
33#include <qdebug.h>
34#include <qabstracttextdocumentlayout.h>
35#include <qimage.h>
36#include <qtextobject.h>
37#include <qfontmetrics.h>
38
39class tst_QAbstractTextDocumentLayout : public QObject
40{
41Q_OBJECT
42
43public:
44 tst_QAbstractTextDocumentLayout();
45 virtual ~tst_QAbstractTextDocumentLayout();
46
47private slots:
48 void getSetCheck();
49 void maximumBlockCount();
50 void anchorAt();
51 void imageAt();
52 void formatAt();
53};
54
55tst_QAbstractTextDocumentLayout::tst_QAbstractTextDocumentLayout()
56{
57}
58
59tst_QAbstractTextDocumentLayout::~tst_QAbstractTextDocumentLayout()
60{
61}
62
63class MyAbstractTextDocumentLayout : public QAbstractTextDocumentLayout
64{
65 Q_OBJECT
66public:
67 MyAbstractTextDocumentLayout(QTextDocument *doc)
68 : QAbstractTextDocumentLayout(doc)
69 , gotFullLayout(false)
70 , blockCount(0)
71 , changeEvents(0)
72 {
73 }
74
75 void draw(QPainter *, const PaintContext &) {}
76 int hitTest(const QPointF &, Qt::HitTestAccuracy) const { return 0; }
77 int pageCount() const { return 0; }
78 QSizeF documentSize() const { return QSizeF(); }
79 QRectF frameBoundingRect(QTextFrame *) const { return QRectF(); }
80 QRectF blockBoundingRect(const QTextBlock &) const { return QRectF(); }
81 void documentChanged(int from, int /* oldLength */, int length) {
82 ++changeEvents;
83
84 QTextBlock last = document()->lastBlock();
85 int lastPos = last.position() + last.length() - 1;
86 if (from == 0 && length == lastPos)
87 gotFullLayout = true;
88 }
89
90 bool gotFullLayout;
91 int blockCount;
92 int changeEvents;
93
94public slots:
95 void blockCountChanged(int bc) { blockCount = bc; }
96};
97
98// Testing get/set functions
99void tst_QAbstractTextDocumentLayout::getSetCheck()
100{
101 QTextDocument doc;
102 MyAbstractTextDocumentLayout obj1(&doc);
103 // QPaintDevice * QAbstractTextDocumentLayout::paintDevice()
104 // void QAbstractTextDocumentLayout::setPaintDevice(QPaintDevice *)
105 QImage *var1 = new QImage(QSize(10,10), QImage::Format_ARGB32_Premultiplied);
106 obj1.setPaintDevice(var1);
107 QCOMPARE(static_cast<QPaintDevice *>(var1), obj1.paintDevice());
108 obj1.setPaintDevice((QPaintDevice *)0);
109 QCOMPARE(static_cast<QPaintDevice *>(0), obj1.paintDevice());
110 delete var1;
111}
112
113void tst_QAbstractTextDocumentLayout::maximumBlockCount()
114{
115 QTextDocument doc;
116 doc.setMaximumBlockCount(10);
117
118 MyAbstractTextDocumentLayout layout(&doc);
119 doc.setDocumentLayout(&layout);
120 QObject::connect(sender: &doc, SIGNAL(blockCountChanged(int)), receiver: &layout, SLOT(blockCountChanged(int)));
121
122 QTextCursor cursor(&doc);
123 for (int i = 0; i < 10; ++i) {
124 cursor.insertBlock();
125 cursor.insertText(text: "bla");
126 }
127
128 QCOMPARE(layout.blockCount, 10);
129
130 layout.gotFullLayout = false;
131 layout.changeEvents = 0;
132 cursor.insertBlock();
133 QCOMPARE(layout.changeEvents, 2);
134 cursor.insertText(text: "foo");
135 QCOMPARE(layout.changeEvents, 3);
136 cursor.insertBlock();
137 QCOMPARE(layout.changeEvents, 5);
138 cursor.insertText(text: "foo");
139 QCOMPARE(layout.changeEvents, 6);
140
141 QVERIFY(!layout.gotFullLayout);
142
143 QCOMPARE(layout.blockCount, 10);
144}
145
146void tst_QAbstractTextDocumentLayout::anchorAt()
147{
148 QTextDocument doc;
149 doc.setHtml("<a href=\"link\">foo</a>");
150 QAbstractTextDocumentLayout *documentLayout = doc.documentLayout();
151 QTextBlock firstBlock = doc.begin();
152 QTextLayout *layout = firstBlock.layout();
153 layout->setPreeditArea(position: doc.toPlainText().length(), text: "xxx");
154
155 doc.setPageSize(QSizeF(1000, 1000));
156 QFontMetrics metrics(layout->font());
157 QPointF blockStart = documentLayout->blockBoundingRect(block: firstBlock).topLeft();
158
159 // anchorAt on start returns link
160 QRect linkBr = metrics.boundingRect(text: "foo");
161 QPointF linkPoint((linkBr.width() / 2) + blockStart.x(), (linkBr.height() / 2) + blockStart.y());
162 QCOMPARE(documentLayout->anchorAt(linkPoint), QString("link"));
163
164 // anchorAt() on top of preedit at end should not assert
165 QRect preeditBr = metrics.boundingRect(text: doc.toPlainText() + "xx");
166 QPointF preeditPoint(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y());
167 QCOMPARE(documentLayout->anchorAt(preeditPoint), QString());
168
169 // preedit at start should not return link
170 layout->setPreeditArea(position: 0, text: "xxx");
171 preeditBr = metrics.boundingRect(text: "xx");
172 preeditPoint = QPointF(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y());
173 QCOMPARE(documentLayout->anchorAt(preeditPoint), QString());
174}
175
176void tst_QAbstractTextDocumentLayout::imageAt()
177{
178 QTextDocument doc;
179 doc.setHtml("foo<a href=\"link\"><img src=\"image\" width=\"50\" height=\"50\"/></a>");
180 QAbstractTextDocumentLayout *documentLayout = doc.documentLayout();
181 QTextBlock firstBlock = doc.begin();
182 QTextLayout *layout = firstBlock.layout();
183 layout->setPreeditArea(position: doc.toPlainText().length(), text: "xxx");
184
185 doc.setPageSize(QSizeF(1000, 1000));
186 QFontMetrics metrics(layout->font());
187 QPointF blockStart = documentLayout->blockBoundingRect(block: firstBlock).topLeft();
188
189 QRect fooBr = metrics.boundingRect(text: "foo");
190 QPointF imagePoint(fooBr.width() + blockStart.x() + 25, blockStart.y() + 25);
191 // imageAt on image returns source
192 QCOMPARE(documentLayout->imageAt(imagePoint), QString("image"));
193 // anchorAt on image returns link
194 QCOMPARE(documentLayout->anchorAt(imagePoint), QString("link"));
195
196 // imageAt on start returns nothing (there's the "foo" text)
197 QPointF fooPoint(blockStart.x() + (fooBr.width() / 2), (fooBr.height() / 2) + blockStart.y());
198 QCOMPARE(documentLayout->imageAt(fooPoint), QString());
199}
200
201void tst_QAbstractTextDocumentLayout::formatAt()
202{
203 QTextDocument doc;
204 doc.setHtml("foo<i><a href=\"link\"><img src=\"image\" width=\"50\" height=\"50\"/></a></i>");
205 QAbstractTextDocumentLayout *documentLayout = doc.documentLayout();
206 QTextBlock firstBlock = doc.begin();
207 QTextLayout *layout = firstBlock.layout();
208 layout->setPreeditArea(position: doc.toPlainText().length(), text: "xxx");
209
210 doc.setPageSize(QSizeF(1000, 1000));
211 QFontMetrics metrics(layout->font());
212 QPointF blockStart = documentLayout->blockBoundingRect(block: firstBlock).topLeft();
213
214 QRect fooBr = metrics.boundingRect(text: "foo");
215 QPointF imagePoint(fooBr.width() + blockStart.x() + 25, blockStart.y() + 25);
216
217 QTextFormat format = documentLayout->formatAt(pos: imagePoint);
218 QVERIFY(format.isCharFormat());
219 QVERIFY(format.toCharFormat().isAnchor());
220 QVERIFY(format.toCharFormat().fontItalic());
221 QVERIFY(format.isImageFormat());
222
223 // move over the unformatted "foo" text)
224 QPointF fooPoint(blockStart.x() + (fooBr.width() / 2), (fooBr.height() / 2) + blockStart.y());
225 format = documentLayout->formatAt(pos: fooPoint);
226 QVERIFY(format.isCharFormat());
227 QVERIFY(!format.toCharFormat().isAnchor());
228 QVERIFY(!format.toCharFormat().fontItalic());
229 QVERIFY(!format.isImageFormat());
230}
231
232QTEST_MAIN(tst_QAbstractTextDocumentLayout)
233#include "tst_qabstracttextdocumentlayout.moc"
234

source code of qtbase/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp