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 <qsettings.h> |
35 | #include <qtextformat.h> |
36 | #include <private/qtextformat_p.h> |
37 | #include <qtextdocument.h> |
38 | #include <qtextcursor.h> |
39 | #include <qtextobject.h> |
40 | #include <qtextlayout.h> |
41 | #include <qabstracttextdocumentlayout.h> |
42 | |
43 | class tst_QTextFormat : public QObject |
44 | { |
45 | Q_OBJECT |
46 | |
47 | private slots: |
48 | void getSetCheck(); |
49 | void defaultAlignment(); |
50 | void testQTextCharFormat() const; |
51 | void testUnderlinePropertyPrecedence(); |
52 | void toFormat(); |
53 | void resolveFont(); |
54 | void testLetterSpacing(); |
55 | void testFontStretch(); |
56 | void getSetTabs(); |
57 | void testTabsUsed(); |
58 | void testFontStyleSetters(); |
59 | void setFont_data(); |
60 | void setFont(); |
61 | void setFont_collection_data(); |
62 | void setFont_collection(); |
63 | void clearCollection(); |
64 | }; |
65 | |
66 | /*! \internal |
67 | This (used to) trigger a crash in: |
68 | |
69 | QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) |
70 | |
71 | which is most easily produced through QSettings. |
72 | */ |
73 | void tst_QTextFormat::testQTextCharFormat() const |
74 | { |
75 | QSettings settings("test" , "test" ); |
76 | QTextCharFormat test; |
77 | |
78 | settings.value(key: "test" , defaultValue: test); |
79 | } |
80 | |
81 | // Testing get/set functions |
82 | void tst_QTextFormat::getSetCheck() |
83 | { |
84 | QTextFormat obj1; |
85 | // int QTextFormat::objectIndex() |
86 | // void QTextFormat::setObjectIndex(int) |
87 | obj1.setObjectIndex(0); |
88 | QCOMPARE(0, obj1.objectIndex()); |
89 | obj1.setObjectIndex(INT_MIN); |
90 | QCOMPARE(INT_MIN, obj1.objectIndex()); |
91 | obj1.setObjectIndex(INT_MAX); |
92 | QCOMPARE(INT_MAX, obj1.objectIndex()); |
93 | } |
94 | |
95 | void tst_QTextFormat::defaultAlignment() |
96 | { |
97 | QTextBlockFormat fmt; |
98 | QVERIFY(!fmt.hasProperty(QTextFormat::BlockAlignment)); |
99 | QCOMPARE(fmt.intProperty(QTextFormat::BlockAlignment), 0); |
100 | QCOMPARE(fmt.alignment(), Qt::AlignLeft); |
101 | } |
102 | |
103 | void tst_QTextFormat::testUnderlinePropertyPrecedence() |
104 | { |
105 | QTextCharFormat format; |
106 | // use normal accessors and check internal state |
107 | format.setUnderlineStyle(QTextCharFormat::NoUnderline); |
108 | QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); |
109 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); |
110 | QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), false); |
111 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).toInt(), 0); |
112 | |
113 | format = QTextCharFormat(); |
114 | format.setUnderlineStyle(QTextCharFormat::SingleUnderline); |
115 | QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); |
116 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); |
117 | QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), true); |
118 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).toInt(), 1); |
119 | |
120 | format = QTextCharFormat(); |
121 | format.setUnderlineStyle(QTextCharFormat::DotLine); |
122 | QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); |
123 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); |
124 | QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), false); |
125 | QVERIFY(format.property(QTextFormat::TextUnderlineStyle).toInt() > 0); |
126 | |
127 | // override accessors and use setProperty to create a false state. |
128 | // then check font() |
129 | format = QTextCharFormat(); |
130 | format.setProperty(propertyId: QTextCharFormat::FontUnderline, value: true); |
131 | QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); |
132 | QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), true); |
133 | QCOMPARE(format.fontUnderline(), true); |
134 | QCOMPARE(format.font().underline(), true); |
135 | |
136 | format = QTextCharFormat(); |
137 | // create conflict. Should use the new property |
138 | format.setProperty(propertyId: QTextCharFormat::TextUnderlineStyle, value: QTextCharFormat::SingleUnderline); |
139 | format.setProperty(propertyId: QTextCharFormat::FontUnderline, value: false); |
140 | QCOMPARE(format.fontUnderline(), true); |
141 | QCOMPARE(format.font().underline(), true); |
142 | |
143 | format = QTextCharFormat(); |
144 | // create conflict. Should use the new property |
145 | format.setProperty(propertyId: QTextCharFormat::TextUnderlineStyle, value: QTextCharFormat::NoUnderline); |
146 | format.setProperty(propertyId: QTextCharFormat::FontUnderline, value: true); |
147 | QCOMPARE(format.fontUnderline(), false); |
148 | QCOMPARE(format.font().underline(), false); |
149 | |
150 | // do it again, but reverse the ordering (we use a QVector internally, so test a LOT ;) |
151 | // create conflict. Should use the new property |
152 | format.setProperty(propertyId: QTextCharFormat::FontUnderline, value: false); |
153 | format.setProperty(propertyId: QTextCharFormat::TextUnderlineStyle, value: QTextCharFormat::SingleUnderline); |
154 | QCOMPARE(format.fontUnderline(), true); |
155 | QCOMPARE(format.font().underline(), true); |
156 | |
157 | format = QTextCharFormat(); |
158 | // create conflict. Should use the new property |
159 | format.setProperty(propertyId: QTextCharFormat::FontUnderline, value: true); |
160 | format.setProperty(propertyId: QTextCharFormat::TextUnderlineStyle, value: QTextCharFormat::NoUnderline); |
161 | QCOMPARE(format.fontUnderline(), false); |
162 | QCOMPARE(format.font().underline(), false); |
163 | } |
164 | |
165 | void tst_QTextFormat::toFormat() |
166 | { |
167 | { |
168 | QTextFormat fmt = QTextFrameFormat(); |
169 | QCOMPARE(fmt.toFrameFormat().type(), int(QTextFormat::FrameFormat)); |
170 | } |
171 | |
172 | { |
173 | QTextFormat fmt = QTextTableFormat(); |
174 | QCOMPARE(fmt.toTableFormat().type(), int(QTextFormat::FrameFormat)); |
175 | QCOMPARE(fmt.toTableFormat().objectType(), int(QTextFormat::TableObject)); |
176 | } |
177 | |
178 | { |
179 | QTextFormat fmt = QTextBlockFormat(); |
180 | QCOMPARE(fmt.toBlockFormat().type(), int(QTextFormat::BlockFormat)); |
181 | } |
182 | |
183 | { |
184 | QTextFormat fmt = QTextCharFormat(); |
185 | QCOMPARE(fmt.toCharFormat().type(), int(QTextFormat::CharFormat)); |
186 | } |
187 | |
188 | { |
189 | QTextFormat fmt = QTextListFormat(); |
190 | QCOMPARE(fmt.toListFormat().type(), int(QTextFormat::ListFormat)); |
191 | } |
192 | } |
193 | |
194 | void tst_QTextFormat::resolveFont() |
195 | { |
196 | QTextDocument doc; |
197 | |
198 | QTextCharFormat fmt; |
199 | fmt.setProperty(propertyId: QTextFormat::ForegroundBrush, value: QColor(Qt::blue)); |
200 | QCOMPARE(fmt.property(QTextFormat::ForegroundBrush).userType(), qMetaTypeId<QColor>()); |
201 | QCOMPARE(fmt.property(QTextFormat::ForegroundBrush).value<QColor>(), QColor(Qt::blue)); |
202 | fmt.setProperty(propertyId: QTextFormat::FontItalic, value: true); |
203 | QTextCursor(&doc).insertText(text: "Test" , format: fmt); |
204 | |
205 | QVector<QTextFormat> formats = doc.allFormats(); |
206 | QCOMPARE(formats.count(), 3); |
207 | |
208 | QCOMPARE(formats.at(2).type(), int(QTextFormat::CharFormat)); |
209 | fmt = formats.at(i: 2).toCharFormat(); |
210 | |
211 | QVERIFY(!fmt.font().underline()); |
212 | QVERIFY(fmt.hasProperty(QTextFormat::ForegroundBrush)); |
213 | |
214 | QFont f; |
215 | f.setUnderline(true); |
216 | doc.setDefaultFont(f); |
217 | formats = doc.allFormats(); |
218 | fmt = formats.at(i: 2).toCharFormat(); |
219 | |
220 | QVERIFY(fmt.font().underline()); |
221 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
222 | |
223 | // verify that deleting a non-existent property does not affect the font resolving |
224 | |
225 | QVERIFY(!fmt.hasProperty(QTextFormat::BackgroundBrush)); |
226 | fmt.clearProperty(propertyId: QTextFormat::BackgroundBrush); |
227 | QVERIFY(!fmt.hasProperty(QTextFormat::BackgroundBrush)); |
228 | |
229 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
230 | QVERIFY(fmt.font().underline()); |
231 | |
232 | // verify that deleting an existent but font _unrelated_ property does not affect the font resolving |
233 | |
234 | QVERIFY(fmt.hasProperty(QTextFormat::ForegroundBrush)); |
235 | fmt.clearProperty(propertyId: QTextFormat::ForegroundBrush); |
236 | QVERIFY(!fmt.hasProperty(QTextFormat::ForegroundBrush)); |
237 | |
238 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
239 | QVERIFY(fmt.font().underline()); |
240 | |
241 | // verify that removing a font property _does_ clear the resolving |
242 | |
243 | QVERIFY(fmt.hasProperty(QTextFormat::FontItalic)); |
244 | fmt.clearProperty(propertyId: QTextFormat::FontItalic); |
245 | QVERIFY(!fmt.hasProperty(QTextFormat::FontItalic)); |
246 | |
247 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
248 | QVERIFY(!fmt.font().underline()); |
249 | QVERIFY(!fmt.font().italic()); |
250 | |
251 | // reset |
252 | fmt = formats.at(i: 2).toCharFormat(); |
253 | |
254 | QVERIFY(fmt.font().underline()); |
255 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
256 | |
257 | // verify that _setting_ an unrelated property does _not_ affect the resolving |
258 | |
259 | QVERIFY(!fmt.hasProperty(QTextFormat::IsAnchor)); |
260 | fmt.setProperty(propertyId: QTextFormat::IsAnchor, value: true); |
261 | QVERIFY(fmt.hasProperty(QTextFormat::IsAnchor)); |
262 | |
263 | QVERIFY(fmt.font().underline()); |
264 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
265 | |
266 | // verify that setting a _related_ font property does affect the resolving |
267 | // |
268 | QVERIFY(!fmt.hasProperty(QTextFormat::FontStrikeOut)); |
269 | fmt.setProperty(propertyId: QTextFormat::FontStrikeOut, value: true); |
270 | QVERIFY(fmt.hasProperty(QTextFormat::FontStrikeOut)); |
271 | |
272 | QVERIFY(!fmt.font().underline()); |
273 | QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); |
274 | QVERIFY(fmt.font().strikeOut()); |
275 | } |
276 | |
277 | |
278 | void tst_QTextFormat::testLetterSpacing() |
279 | { |
280 | QTextCharFormat format; |
281 | |
282 | QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacing), false); |
283 | QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacingType), false); |
284 | |
285 | format.setFontLetterSpacingType(QFont::AbsoluteSpacing); |
286 | QCOMPARE(format.font().letterSpacingType(), QFont::AbsoluteSpacing); |
287 | |
288 | format.setFontLetterSpacing(10.0); |
289 | QCOMPARE(format.font().letterSpacing(), 10.0); |
290 | |
291 | QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacing), true); |
292 | QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 10.0); |
293 | QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::AbsoluteSpacing)); |
294 | |
295 | format.setFontLetterSpacingType(QFont::PercentageSpacing); |
296 | QCOMPARE(format.font().letterSpacingType(), QFont::PercentageSpacing); |
297 | |
298 | format.setFontLetterSpacing(110.0); |
299 | QCOMPARE(format.font().letterSpacing(), 110.0); |
300 | |
301 | QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 110.0); |
302 | QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::PercentageSpacing)); |
303 | |
304 | format.setFontLetterSpacingType(QFont::AbsoluteSpacing); |
305 | QCOMPARE(format.font().letterSpacingType(), QFont::AbsoluteSpacing); |
306 | |
307 | format.setFontLetterSpacing(10.0); |
308 | QCOMPARE(format.font().letterSpacing(), 10.0); |
309 | |
310 | QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::AbsoluteSpacing)); |
311 | QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 10.0); |
312 | } |
313 | |
314 | void tst_QTextFormat::testFontStretch() |
315 | { |
316 | QTextCharFormat format; |
317 | |
318 | QCOMPARE(format.hasProperty(QTextFormat::FontStretch), false); |
319 | |
320 | format.setFontStretch(130.0); |
321 | |
322 | QCOMPARE(format.property(QTextFormat::FontStretch).toInt(), 130); |
323 | } |
324 | |
325 | void tst_QTextFormat::getSetTabs() |
326 | { |
327 | class Comparator { |
328 | public: |
329 | Comparator(const QList<QTextOption::Tab> &tabs, const QList<QTextOption::Tab> &tabs2) |
330 | { |
331 | QCOMPARE(tabs.count(), tabs2.count()); |
332 | for(int i=0; i < tabs.count(); i++) { |
333 | QTextOption::Tab t1 = tabs[i]; |
334 | QTextOption::Tab t2 = tabs2[i]; |
335 | QCOMPARE(t1.position, t2.position); |
336 | QCOMPARE(t1.type, t2.type); |
337 | QCOMPARE(t1.delimiter, t2.delimiter); |
338 | } |
339 | } |
340 | }; |
341 | |
342 | QList<QTextOption::Tab> tabs; |
343 | QTextBlockFormat format; |
344 | format.setTabPositions(tabs); |
345 | Comparator c1(tabs, format.tabPositions()); |
346 | |
347 | QTextOption::Tab tab1; |
348 | tab1.position = 1234; |
349 | tabs.append(t: tab1); |
350 | format.setTabPositions(tabs); |
351 | Comparator c2(tabs, format.tabPositions()); |
352 | |
353 | QTextOption::Tab tab2(3456, QTextOption::RightTab, QChar('x')); |
354 | tabs.append(t: tab2); |
355 | format.setTabPositions(tabs); |
356 | Comparator c3(tabs, format.tabPositions()); |
357 | } |
358 | |
359 | void tst_QTextFormat::testTabsUsed() |
360 | { |
361 | QTextDocument doc; |
362 | QTextCursor cursor(&doc); |
363 | |
364 | QList<QTextOption::Tab> tabs; |
365 | QTextBlockFormat format; |
366 | QTextOption::Tab tab; |
367 | tab.position = 100; |
368 | tabs.append(t: tab); |
369 | format.setTabPositions(tabs); |
370 | cursor.mergeBlockFormat(modifier: format); |
371 | cursor.insertText(text: "foo\tbar" ); |
372 | //doc.setPageSize(QSizeF(200, 200)); |
373 | doc.documentLayout()->pageCount(); // force layout; |
374 | |
375 | QTextBlock block = doc.begin(); |
376 | QTextLayout *layout = block.layout(); |
377 | QVERIFY(layout); |
378 | QCOMPARE(layout->lineCount(), 1); |
379 | QTextLine line = layout->lineAt(i: 0); |
380 | QCOMPARE(line.cursorToX(4), 100.); |
381 | |
382 | QTextOption option = layout->textOption(); |
383 | QCOMPARE(option.tabs().count(), tabs.count()); |
384 | |
385 | } |
386 | |
387 | void tst_QTextFormat::testFontStyleSetters() |
388 | { |
389 | QTextCharFormat format; |
390 | |
391 | // test the setters |
392 | format.setFontStyleHint(hint: QFont::Serif); |
393 | QCOMPARE(format.font().styleHint(), QFont::Serif); |
394 | QCOMPARE(format.font().styleStrategy(), QFont::PreferDefault); |
395 | format.setFontStyleStrategy(QFont::PreferOutline); |
396 | QCOMPARE(format.font().styleStrategy(), QFont::PreferOutline); |
397 | |
398 | // test setting properties through setFont() |
399 | QFont font; |
400 | font.setStyleHint(QFont::SansSerif, QFont::PreferAntialias); |
401 | format.setFont(font); |
402 | QCOMPARE(format.font().styleHint(), QFont::SansSerif); |
403 | QCOMPARE(format.font().styleStrategy(), QFont::PreferAntialias); |
404 | |
405 | // test kerning |
406 | format.setFontKerning(false); |
407 | QCOMPARE(format.font().kerning(), false); |
408 | format.setFontKerning(true); |
409 | QCOMPARE(format.font().kerning(), true); |
410 | font.setKerning(false); |
411 | format.setFont(font); |
412 | QCOMPARE(format.font().kerning(), false); |
413 | } |
414 | |
415 | Q_DECLARE_METATYPE(QTextCharFormat) |
416 | |
417 | void tst_QTextFormat::setFont_data() |
418 | { |
419 | QTest::addColumn<QTextCharFormat>(name: "format1" ); |
420 | QTest::addColumn<QTextCharFormat>(name: "format2" ); |
421 | QTest::addColumn<bool>(name: "overrideAll" ); |
422 | |
423 | QTextCharFormat format1; |
424 | format1.setFontStyleHint(hint: QFont::Serif); |
425 | format1.setFontStyleStrategy(QFont::PreferOutline); |
426 | format1.setFontCapitalization(QFont::AllUppercase); |
427 | format1.setFontKerning(true); |
428 | |
429 | { |
430 | QTest::newRow(dataTag: "noop|override" ) << format1 << format1 << true; |
431 | QTest::newRow(dataTag: "noop|inherit" ) << format1 << format1 << false; |
432 | } |
433 | |
434 | { |
435 | QTextCharFormat format2; |
436 | format2.setFontStyleHint(hint: QFont::SansSerif); |
437 | format2.setFontStyleStrategy(QFont::PreferAntialias); |
438 | format2.setFontCapitalization(QFont::MixedCase); |
439 | format2.setFontKerning(false); |
440 | |
441 | QTest::newRow(dataTag: "coverage|override" ) << format1 << format2 << true; |
442 | QTest::newRow(dataTag: "coverage|inherit" ) << format1 << format2 << false; |
443 | } |
444 | |
445 | { |
446 | QTextCharFormat format2; |
447 | format2.setFontStyleHint(hint: QFont::SansSerif); |
448 | format2.setFontStyleStrategy(QFont::PreferAntialias); |
449 | |
450 | QTest::newRow(dataTag: "partial|override" ) << format1 << format2 << true; |
451 | QTest::newRow(dataTag: "partial|inherit" ) << format1 << format2 << false; |
452 | } |
453 | } |
454 | |
455 | void tst_QTextFormat::setFont() |
456 | { |
457 | QFETCH(QTextCharFormat, format1); |
458 | QFETCH(QTextCharFormat, format2); |
459 | QFETCH(bool, overrideAll); |
460 | |
461 | QTextCharFormat f; |
462 | |
463 | f.merge(other: format1); |
464 | QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); |
465 | QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); |
466 | QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); |
467 | QCOMPARE(f.fontKerning(), format1.fontKerning()); |
468 | |
469 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
470 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
471 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
472 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
473 | |
474 | f.merge(other: format2); |
475 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
476 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
477 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
478 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
479 | |
480 | if (format2.hasProperty(propertyId: QTextFormat::FontStyleHint)) |
481 | QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint()); |
482 | else |
483 | QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint()); |
484 | if (format2.hasProperty(propertyId: QTextFormat::FontStyleStrategy)) |
485 | QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy()); |
486 | else |
487 | QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy()); |
488 | if (format2.hasProperty(propertyId: QTextFormat::FontCapitalization)) |
489 | QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization()); |
490 | else |
491 | QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization()); |
492 | if (format2.hasProperty(propertyId: QTextFormat::FontKerning)) |
493 | QCOMPARE(f.font().kerning(), format2.fontKerning()); |
494 | else |
495 | QCOMPARE(f.font().kerning(), format1.fontKerning()); |
496 | |
497 | |
498 | QFont font1 = format1.font(); |
499 | QFont font2 = format2.font(); |
500 | |
501 | f = QTextCharFormat(); |
502 | |
503 | { |
504 | QTextCharFormat tmp; |
505 | tmp.setFont(font: font1, behavior: overrideAll ? QTextCharFormat::FontPropertiesAll |
506 | : QTextCharFormat::FontPropertiesSpecifiedOnly); |
507 | f.merge(other: tmp); |
508 | } |
509 | QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); |
510 | QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); |
511 | QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); |
512 | QCOMPARE(f.fontKerning(), format1.fontKerning()); |
513 | |
514 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
515 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
516 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
517 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
518 | |
519 | { |
520 | QTextCharFormat tmp; |
521 | tmp.setFont(font: font2, behavior: overrideAll ? QTextCharFormat::FontPropertiesAll |
522 | : QTextCharFormat::FontPropertiesSpecifiedOnly); |
523 | f.merge(other: tmp); |
524 | } |
525 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
526 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
527 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
528 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
529 | |
530 | if (overrideAll || (font2.resolve() & QFont::StyleHintResolved)) |
531 | QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint()); |
532 | else |
533 | QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint()); |
534 | if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved)) |
535 | QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy()); |
536 | else |
537 | QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy()); |
538 | if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved)) |
539 | QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization()); |
540 | else |
541 | QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization()); |
542 | if (overrideAll || (font2.resolve() & QFont::KerningResolved)) |
543 | QCOMPARE(f.font().kerning(), font2.kerning()); |
544 | else |
545 | QCOMPARE(f.font().kerning(), font1.kerning()); |
546 | } |
547 | |
548 | void tst_QTextFormat::setFont_collection_data() |
549 | { |
550 | setFont_data(); |
551 | } |
552 | |
553 | void tst_QTextFormat::setFont_collection() |
554 | { |
555 | QFETCH(QTextCharFormat, format1); |
556 | QFETCH(QTextCharFormat, format2); |
557 | QFETCH(bool, overrideAll); |
558 | |
559 | QFont font1 = format1.font(); |
560 | QFont font2 = format2.font(); |
561 | |
562 | { |
563 | QTextFormatCollection collection; |
564 | collection.setDefaultFont(font1); |
565 | |
566 | int formatIndex = collection.indexForFormat(f: format1); |
567 | QTextCharFormat f = collection.charFormat(index: formatIndex); |
568 | |
569 | QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); |
570 | QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); |
571 | QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); |
572 | QCOMPARE(f.fontKerning(), format1.fontKerning()); |
573 | |
574 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
575 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
576 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
577 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
578 | } |
579 | { |
580 | QTextFormatCollection collection; |
581 | collection.setDefaultFont(font1); |
582 | |
583 | int formatIndex = collection.indexForFormat(f: format2); |
584 | QTextCharFormat f = collection.charFormat(index: formatIndex); |
585 | |
586 | if (format2.hasProperty(propertyId: QTextFormat::FontStyleHint)) |
587 | QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint()); |
588 | else |
589 | QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint()); |
590 | if (format2.hasProperty(propertyId: QTextFormat::FontStyleStrategy)) |
591 | QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy()); |
592 | else |
593 | QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy()); |
594 | if (format2.hasProperty(propertyId: QTextFormat::FontCapitalization)) |
595 | QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization()); |
596 | else |
597 | QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization()); |
598 | if (format2.hasProperty(propertyId: QTextFormat::FontKerning)) |
599 | QCOMPARE(f.font().kerning(), format2.fontKerning()); |
600 | else |
601 | QCOMPARE(f.font().kerning(), format1.fontKerning()); |
602 | } |
603 | |
604 | { |
605 | QTextFormatCollection collection; |
606 | collection.setDefaultFont(font1); |
607 | |
608 | QTextCharFormat tmp; |
609 | tmp.setFont(font: font1, behavior: overrideAll ? QTextCharFormat::FontPropertiesAll |
610 | : QTextCharFormat::FontPropertiesSpecifiedOnly); |
611 | int formatIndex = collection.indexForFormat(f: tmp); |
612 | QTextCharFormat f = collection.charFormat(index: formatIndex); |
613 | |
614 | QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); |
615 | QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); |
616 | QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); |
617 | QCOMPARE(f.fontKerning(), format1.fontKerning()); |
618 | |
619 | QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); |
620 | QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); |
621 | QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); |
622 | QCOMPARE(f.font().kerning(), f.fontKerning()); |
623 | } |
624 | { |
625 | QTextFormatCollection collection; |
626 | collection.setDefaultFont(font1); |
627 | |
628 | QTextCharFormat tmp; |
629 | tmp.setFont(font: font2, behavior: overrideAll ? QTextCharFormat::FontPropertiesAll |
630 | : QTextCharFormat::FontPropertiesSpecifiedOnly); |
631 | int formatIndex = collection.indexForFormat(f: tmp); |
632 | QTextCharFormat f = collection.charFormat(index: formatIndex); |
633 | |
634 | if (overrideAll || (font2.resolve() & QFont::StyleHintResolved)) |
635 | QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint()); |
636 | else |
637 | QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint()); |
638 | if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved)) |
639 | QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy()); |
640 | else |
641 | QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy()); |
642 | if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved)) |
643 | QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization()); |
644 | else |
645 | QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization()); |
646 | if (overrideAll || (font2.resolve() & QFont::KerningResolved)) |
647 | QCOMPARE(f.font().kerning(), font2.kerning()); |
648 | else |
649 | QCOMPARE(f.font().kerning(), font1.kerning()); |
650 | } |
651 | } |
652 | |
653 | void tst_QTextFormat::clearCollection() |
654 | { |
655 | QTextFormatCollection collection; |
656 | QFont f; |
657 | f.setUnderline(true); |
658 | collection.setDefaultFont(f); |
659 | QTextCharFormat charFormat; |
660 | charFormat.setFontStyleHint(hint: QFont::SansSerif); |
661 | int formatIndex = collection.indexForFormat(f: charFormat); |
662 | QCOMPARE(formatIndex, 0); |
663 | QTextCharFormat charFormat2; |
664 | charFormat2.setUnderlineStyle(QTextCharFormat::SingleUnderline); |
665 | int formatIndex2 = collection.indexForFormat(f: charFormat2); |
666 | QCOMPARE(formatIndex2, 1); |
667 | QCOMPARE(collection.formats.count(), 2); |
668 | QCOMPARE(collection.hashes.count(), 2); |
669 | QCOMPARE(collection.defaultFont(), f); |
670 | |
671 | collection.clear(); |
672 | QCOMPARE(collection.formats.count(), 0); |
673 | QCOMPARE(collection.hashes.count(), 0); |
674 | QCOMPARE(collection.indexForFormat(charFormat2), 0); |
675 | QCOMPARE(collection.formats.count(), 1); |
676 | QCOMPARE(collection.hashes.count(), 1); |
677 | QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont |
678 | } |
679 | |
680 | QTEST_MAIN(tst_QTextFormat) |
681 | #include "tst_qtextformat.moc" |
682 | |