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>
This commit is contained in:
parent
f6723cf0d4
commit
f26928cccf
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
CONFIG += testcase
|
||||
CONFIG += parallel_test
|
||||
TARGET = tst_qtextformat
|
||||
QT += testlib
|
||||
QT += testlib core-private gui-private
|
||||
SOURCES += 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"
|
||||
|
Loading…
Reference in New Issue
Block a user