summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2014-01-17 17:38:55 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-31 00:24:48 +0100
commitf26928cccf7e0fd9f06236476f2a6b52151e5dca (patch)
tree9464f786b5c27d1b5669e0c09eb87414f9529d64
parentf6723cf0d479823a34e874bc4cc9ff43e040793a (diff)
Allow QTextCharFormat::setFont() to skip unresolved font props
This makes the font merging possible and solves an issue with the default font properties inheritance when used in conjunction with QTextFormatCollection. Change-Id: If8b543c011122dde9f086f5d696df3b042f7b90c Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/gui/text/qtextformat.cpp103
-rw-r--r--src/gui/text/qtextformat.h8
-rw-r--r--src/gui/text/qtexthtmlparser.cpp28
-rw-r--r--tests/auto/gui/text/qtextformat/qtextformat.pro2
-rw-r--r--tests/auto/gui/text/qtextformat/tst_qtextformat.cpp243
5 files changed, 332 insertions, 52 deletions
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 641a2ceb8a..d2b91c1f9f 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -1879,36 +1879,93 @@ QStringList QTextCharFormat::anchorNames() const
*/
/*!
+ \enum QTextCharFormat::FontPropertiesInheritanceBehavior
+ \since 5.3
+
+ This enum specifies how the setFont() function should behave with
+ respect to unset font properties.
+
+ \value FontPropertiesSpecifiedOnly If a property is not explicitly set, do not
+ change the text format's property value.
+ \value FontPropertiesAll If a property is not explicitly set, override the
+ text format's property with a default value.
+
+ \sa setFont()
+*/
+
+/*!
+ \overload
+
Sets the text format's \a font.
+
+ \sa font()
*/
void QTextCharFormat::setFont(const QFont &font)
{
- setFontFamily(font.family());
+ setFont(font, FontPropertiesAll);
+}
- const qreal pointSize = font.pointSizeF();
- if (pointSize > 0) {
- setFontPointSize(pointSize);
- } else {
- const int pixelSize = font.pixelSize();
- if (pixelSize > 0)
- setProperty(QTextFormat::FontPixelSize, pixelSize);
+/*!
+ \since 5.3
+
+ Sets the text format's \a font.
+
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is treated like as it were set with default value;
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is ignored and the respective property value
+ remains unchanged.
+
+ \sa font()
+*/
+void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior)
+{
+ const uint mask = behavior == FontPropertiesAll ? uint(QFont::AllPropertiesResolved)
+ : font.resolve();
+
+ if (mask & QFont::FamilyResolved)
+ setFontFamily(font.family());
+ if (mask & QFont::SizeResolved) {
+ const qreal pointSize = font.pointSizeF();
+ if (pointSize > 0) {
+ setFontPointSize(pointSize);
+ } else {
+ const int pixelSize = font.pixelSize();
+ if (pixelSize > 0)
+ setProperty(QTextFormat::FontPixelSize, pixelSize);
+ }
}
- setFontWeight(font.weight());
- setFontItalic(font.italic());
- setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
- setFontOverline(font.overline());
- setFontStrikeOut(font.strikeOut());
- setFontFixedPitch(font.fixedPitch());
- setFontCapitalization(font.capitalization());
- setFontWordSpacing(font.wordSpacing());
- setFontLetterSpacingType(font.letterSpacingType());
- setFontLetterSpacing(font.letterSpacing());
- setFontStretch(font.stretch());
- setFontStyleHint(font.styleHint());
- setFontStyleStrategy(font.styleStrategy());
- setFontHintingPreference(font.hintingPreference());
- setFontKerning(font.kerning());
+ if (mask & QFont::WeightResolved)
+ setFontWeight(font.weight());
+ if (mask & QFont::StyleResolved)
+ setFontItalic(font.style() != QFont::StyleNormal);
+ if (mask & QFont::UnderlineResolved)
+ setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
+ if (mask & QFont::OverlineResolved)
+ setFontOverline(font.overline());
+ if (mask & QFont::StrikeOutResolved)
+ setFontStrikeOut(font.strikeOut());
+ if (mask & QFont::FixedPitchResolved)
+ setFontFixedPitch(font.fixedPitch());
+ if (mask & QFont::CapitalizationResolved)
+ setFontCapitalization(font.capitalization());
+ if (mask & QFont::LetterSpacingResolved)
+ setFontWordSpacing(font.wordSpacing());
+ if (mask & QFont::LetterSpacingResolved) {
+ setFontLetterSpacingType(font.letterSpacingType());
+ setFontLetterSpacing(font.letterSpacing());
+ }
+ if (mask & QFont::StretchResolved)
+ setFontStretch(font.stretch());
+ if (mask & QFont::StyleHintResolved)
+ setFontStyleHint(font.styleHint());
+ if (mask & QFont::StyleStrategyResolved)
+ setFontStyleStrategy(font.styleStrategy());
+ if (mask & QFont::HintingPreferenceResolved)
+ setFontHintingPreference(font.hintingPreference());
+ if (mask & QFont::KerningResolved)
+ setFontKerning(font.kerning());
}
/*!
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index c04ac3876b..1906a8a0c2 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -408,7 +408,13 @@ public:
QTextCharFormat();
bool isValid() const { return isCharFormat(); }
- void setFont(const QFont &font);
+
+ enum FontPropertiesInheritanceBehavior {
+ FontPropertiesSpecifiedOnly,
+ FontPropertiesAll
+ };
+ void setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior);
+ void setFont(const QFont &font); // ### Qt6: Merge with above
QFont font() const;
inline void setFontFamily(const QString &family)
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 3cb61b9eae..e8a02c44b2 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1361,33 +1361,7 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
QFont f;
int adjustment = -255;
extractor.extractFont(&f, &adjustment);
- if (f.resolve() & QFont::SizeResolved) {
- if (f.pointSize() > 0) {
- charFormat.setFontPointSize(f.pointSize());
- } else if (f.pixelSize() > 0) {
- charFormat.setProperty(QTextFormat::FontPixelSize, f.pixelSize());
- }
- }
- if (f.resolve() & QFont::StyleResolved)
- charFormat.setFontItalic(f.style() != QFont::StyleNormal);
-
- if (f.resolve() & QFont::WeightResolved)
- charFormat.setFontWeight(f.weight());
-
- if (f.resolve() & QFont::FamilyResolved)
- charFormat.setFontFamily(f.family());
-
- if (f.resolve() & QFont::UnderlineResolved)
- charFormat.setUnderlineStyle(f.underline() ? QTextCharFormat::SingleUnderline : QTextCharFormat::NoUnderline);
-
- if (f.resolve() & QFont::OverlineResolved)
- charFormat.setFontOverline(f.overline());
-
- if (f.resolve() & QFont::StrikeOutResolved)
- charFormat.setFontStrikeOut(f.strikeOut());
-
- if (f.resolve() & QFont::CapitalizationResolved)
- charFormat.setFontCapitalization(f.capitalization());
+ charFormat.setFont(f, QTextCharFormat::FontPropertiesSpecifiedOnly);
if (adjustment >= -1)
charFormat.setProperty(QTextFormat::FontSizeAdjustment, adjustment);
diff --git a/tests/auto/gui/text/qtextformat/qtextformat.pro b/tests/auto/gui/text/qtextformat/qtextformat.pro
index b137dac9eb..c64d266916 100644
--- a/tests/auto/gui/text/qtextformat/qtextformat.pro
+++ b/tests/auto/gui/text/qtextformat/qtextformat.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qtextformat
-QT += testlib
+QT += testlib core-private gui-private
SOURCES += tst_qtextformat.cpp
diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
index 1eb073d3b4..beb5069f06 100644
--- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
+++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
@@ -46,6 +46,7 @@
#include <qdebug.h>
#include <qsettings.h>
#include <qtextformat.h>
+#include <private/qtextformat_p.h>
#include <qtextdocument.h>
#include <qtextcursor.h>
#include <qtextobject.h>
@@ -68,6 +69,10 @@ private slots:
void getSetTabs();
void testTabsUsed();
void testFontStyleSetters();
+ void setFont_data();
+ void setFont();
+ void setFont_collection_data();
+ void setFont_collection();
};
/*! \internal
@@ -410,5 +415,243 @@ void tst_QTextFormat::testFontStyleSetters()
QCOMPARE(format.font().kerning(), false);
}
+Q_DECLARE_METATYPE(QTextCharFormat)
+
+void tst_QTextFormat::setFont_data()
+{
+ QTest::addColumn<QTextCharFormat>("format1");
+ QTest::addColumn<QTextCharFormat>("format2");
+ QTest::addColumn<bool>("overrideAll");
+
+ QTextCharFormat format1;
+ format1.setFontStyleHint(QFont::Serif);
+ format1.setFontStyleStrategy(QFont::PreferOutline);
+ format1.setFontCapitalization(QFont::AllUppercase);
+ format1.setFontKerning(true);
+
+ {
+ QTest::newRow("noop|override") << format1 << format1 << true;
+ QTest::newRow("noop|inherit") << format1 << format1 << false;
+ }
+
+ {
+ QTextCharFormat format2;
+ format2.setFontStyleHint(QFont::SansSerif);
+ format2.setFontStyleStrategy(QFont::PreferAntialias);
+ format2.setFontCapitalization(QFont::MixedCase);
+ format2.setFontKerning(false);
+
+ QTest::newRow("coverage|override") << format1 << format2 << true;
+ QTest::newRow("coverage|inherit") << format1 << format2 << false;
+ }
+
+ {
+ QTextCharFormat format2;
+ format2.setFontStyleHint(QFont::SansSerif);
+ format2.setFontStyleStrategy(QFont::PreferAntialias);
+
+ QTest::newRow("partial|override") << format1 << format2 << true;
+ QTest::newRow("partial|inherit") << format1 << format2 << false;
+ }
+}
+
+void tst_QTextFormat::setFont()
+{
+ QFETCH(QTextCharFormat, format1);
+ QFETCH(QTextCharFormat, format2);
+ QFETCH(bool, overrideAll);
+
+ QTextCharFormat f;
+
+ f.merge(format1);
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ f.merge(format2);
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ if (format2.hasProperty(QTextFormat::FontStyleHint))
+ QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint());
+ if (format2.hasProperty(QTextFormat::FontStyleStrategy))
+ QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy());
+ if (format2.hasProperty(QTextFormat::FontCapitalization))
+ QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization());
+ if (format2.hasProperty(QTextFormat::FontKerning))
+ QCOMPARE(f.font().kerning(), format2.fontKerning());
+ else
+ QCOMPARE(f.font().kerning(), format1.fontKerning());
+
+
+ QFont font1 = format1.font();
+ QFont font2 = format2.font();
+
+ f = QTextCharFormat();
+
+ {
+ QTextCharFormat tmp;
+ tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ f.merge(tmp);
+ }
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ {
+ QTextCharFormat tmp;
+ tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ f.merge(tmp);
+ }
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ if (overrideAll || (font2.resolve() & QFont::StyleHintResolved))
+ QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint());
+ if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved))
+ QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy());
+ if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved))
+ QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization());
+ if (overrideAll || (font2.resolve() & QFont::KerningResolved))
+ QCOMPARE(f.font().kerning(), font2.kerning());
+ else
+ QCOMPARE(f.font().kerning(), font1.kerning());
+}
+
+void tst_QTextFormat::setFont_collection_data()
+{
+ setFont_data();
+}
+
+void tst_QTextFormat::setFont_collection()
+{
+ QFETCH(QTextCharFormat, format1);
+ QFETCH(QTextCharFormat, format2);
+ QFETCH(bool, overrideAll);
+
+ QFont font1 = format1.font();
+ QFont font2 = format2.font();
+
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ int formatIndex = collection.indexForFormat(format1);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+ }
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ int formatIndex = collection.indexForFormat(format2);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ if (format2.hasProperty(QTextFormat::FontStyleHint))
+ QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint());
+ if (format2.hasProperty(QTextFormat::FontStyleStrategy))
+ QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy());
+ if (format2.hasProperty(QTextFormat::FontCapitalization))
+ QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization());
+ if (format2.hasProperty(QTextFormat::FontKerning))
+ QCOMPARE(f.font().kerning(), format2.fontKerning());
+ else
+ QCOMPARE(f.font().kerning(), format1.fontKerning());
+ }
+
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ QTextCharFormat tmp;
+ tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ int formatIndex = collection.indexForFormat(tmp);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+ }
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ QTextCharFormat tmp;
+ tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ int formatIndex = collection.indexForFormat(tmp);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ if (overrideAll || (font2.resolve() & QFont::StyleHintResolved))
+ QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint());
+ if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved))
+ QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy());
+ if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved))
+ QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization());
+ if (overrideAll || (font2.resolve() & QFont::KerningResolved))
+ QCOMPARE(f.font().kerning(), font2.kerning());
+ else
+ QCOMPARE(f.font().kerning(), font1.kerning());
+ }
+}
+
QTEST_MAIN(tst_QTextFormat)
#include "tst_qtextformat.moc"