Add support for font features and variable axes to QTextCharFormat
These can be set on the font directly, but had not been added to QTextCharFormat, so there would be no way to override them by formatting in a rich text document. Fixes: QTBUG-134060 Change-Id: I4494e24cb9b99d84fb376ba895e2461fc3cd054b Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
parent
9b9a2398f3
commit
fb89d498a9
@ -91,7 +91,7 @@ public:
|
||||
Qt_6_8 = Qt_6_7,
|
||||
Qt_6_9 = Qt_6_7,
|
||||
Qt_6_10 = 23,
|
||||
Qt_6_11 = Qt_6_10,
|
||||
Qt_6_11 = 24,
|
||||
Qt_DefaultCompiledVersion = Qt_6_11
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 12, 0)
|
||||
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
|
||||
|
@ -388,6 +388,20 @@ void QTextFormatPrivate::recalcFont() const
|
||||
case QTextFormat::FontKerning:
|
||||
f.setKerning(props.at(i).value.toBool());
|
||||
break;
|
||||
case QTextFormat::FontFeatures:
|
||||
{
|
||||
const auto fontFeatures = props.at(i).value.value<QHash<QFont::Tag, quint32>>();
|
||||
for (auto it = fontFeatures.constBegin(); it != fontFeatures.constEnd(); ++it)
|
||||
f.setFeature(it.key(), it.value());
|
||||
break;
|
||||
}
|
||||
case QTextFormat::FontVariableAxes:
|
||||
{
|
||||
const auto fontVariableAxes = props.at(i).value.value<QHash<QFont::Tag, float>>();
|
||||
for (auto it = fontVariableAxes.constBegin(); it != fontVariableAxes.constEnd(); ++it)
|
||||
f.setVariableAxis(it.key(), it.value());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -404,6 +418,16 @@ void QTextFormatPrivate::recalcFont() const
|
||||
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt)
|
||||
{
|
||||
QMap<int, QVariant> properties = fmt.properties();
|
||||
if (stream.version() < QDataStream::Qt_6_11) {
|
||||
auto it = properties.constFind(QTextFormat::FontFeatures);
|
||||
if (it != properties.cend())
|
||||
properties.erase(it);
|
||||
|
||||
it = properties.constFind(QTextFormat::FontVariableAxes);
|
||||
if (it != properties.cend())
|
||||
properties.erase(it);
|
||||
}
|
||||
|
||||
if (stream.version() < QDataStream::Qt_6_0) {
|
||||
auto it = properties.constFind(QTextFormat::FontLetterSpacingType);
|
||||
if (it != properties.cend()) {
|
||||
@ -447,14 +471,17 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
|
||||
for (QMap<qint32, QVariant>::ConstIterator it = properties.constBegin();
|
||||
it != properties.constEnd(); ++it) {
|
||||
qint32 key = it.key();
|
||||
if (key == QTextFormat::OldFontLetterSpacingType)
|
||||
key = QTextFormat::FontLetterSpacingType;
|
||||
else if (key == QTextFormat::OldFontStretch)
|
||||
key = QTextFormat::FontStretch;
|
||||
else if (key == QTextFormat::OldTextUnderlineColor)
|
||||
key = QTextFormat::TextUnderlineColor;
|
||||
else if (key == QTextFormat::OldFontFamily)
|
||||
key = QTextFormat::FontFamilies;
|
||||
|
||||
if (stream.version() < QDataStream::Qt_6_0) {
|
||||
if (key == QTextFormat::OldFontLetterSpacingType)
|
||||
key = QTextFormat::FontLetterSpacingType;
|
||||
else if (key == QTextFormat::OldFontStretch)
|
||||
key = QTextFormat::FontStretch;
|
||||
else if (key == QTextFormat::OldTextUnderlineColor)
|
||||
key = QTextFormat::TextUnderlineColor;
|
||||
else if (key == QTextFormat::OldFontFamily)
|
||||
key = QTextFormat::FontFamilies;
|
||||
}
|
||||
fmt.d->insertProperty(key, it.value());
|
||||
}
|
||||
|
||||
@ -653,6 +680,10 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextTableCellFormat &
|
||||
\value FontKerning Specifies whether the font has kerning turned on.
|
||||
\value FontHintingPreference Controls the use of hinting according to values
|
||||
of the QFont::HintingPreference enum.
|
||||
\value FontFeatures [since 6.11] Assigns integer numbers to typographical features. See
|
||||
\l{QFont::setFeature()} for additional information.
|
||||
\value FontVariableAxes [since 6.11] Assigns floating point numbers to variable axes in variable
|
||||
fonts. See \l{QFont::setVariableAxis()} for additional information.
|
||||
|
||||
\omitvalue FirstFontProperty
|
||||
\omitvalue LastFontProperty
|
||||
@ -1809,6 +1840,55 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
|
||||
\sa font(), QFont::hintingPreference()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 6.11
|
||||
|
||||
Sets the typographical features of the text format's font to be \a fontFeatures.
|
||||
|
||||
\sa QFont::setFeature()
|
||||
*/
|
||||
void QTextCharFormat::setFontFeatures(const QHash<QFont::Tag, quint32> &fontFeatures)
|
||||
{
|
||||
setProperty(FontFeatures, QVariant::fromValue(fontFeatures));
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.11
|
||||
|
||||
Gets the typographical features of the text format's font.
|
||||
|
||||
\sa setFontFeatures()
|
||||
*/
|
||||
QHash<QFont::Tag, quint32> QTextCharFormat::fontFeatures() const
|
||||
{
|
||||
return property(FontFeatures).value<QHash<QFont::Tag, quint32>>();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.11
|
||||
|
||||
Sets the variable axes of the text format's font to be \a fontVariableAxes.
|
||||
|
||||
\sa QFont::setVariableAxis()
|
||||
*/
|
||||
void QTextCharFormat::setFontVariableAxes(const QHash<QFont::Tag, float> &fontVariableAxes)
|
||||
{
|
||||
setProperty(FontVariableAxes, QVariant::fromValue(fontVariableAxes));
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.11
|
||||
|
||||
Gets the variable axes of the text format's font.
|
||||
|
||||
\sa setFontVariableAxes()
|
||||
*/
|
||||
QHash<QFont::Tag, float> QTextCharFormat::fontVariableAxes() const
|
||||
{
|
||||
return property(FontVariableAxes).value<QHash<QFont::Tag, float>>();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\fn QPen QTextCharFormat::textOutline() const
|
||||
|
||||
@ -2145,6 +2225,22 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi
|
||||
setFontHintingPreference(font.hintingPreference());
|
||||
if (mask & QFont::KerningResolved)
|
||||
setFontKerning(font.kerning());
|
||||
if (mask & QFont::FeaturesResolved) {
|
||||
const auto tags = font.featureTags();
|
||||
|
||||
QHash<QFont::Tag, quint32> fontFeatures;
|
||||
for (QFont::Tag tag : tags)
|
||||
fontFeatures.insert(tag, font.featureValue(tag));
|
||||
setFontFeatures(fontFeatures);
|
||||
}
|
||||
if (mask & QFont::VariableAxesResolved) {
|
||||
const auto tags = font.variableAxisTags();
|
||||
|
||||
QHash<QFont::Tag, float> fontVariableAxes;
|
||||
for (QFont::Tag tag : tags)
|
||||
fontVariableAxes.insert(tag, font.variableAxisValue(tag));
|
||||
setFontVariableAxes(fontVariableAxes);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qhash.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -159,7 +160,9 @@ public:
|
||||
FontStrikeOut = 0x2007,
|
||||
FontFixedPitch = 0x2008,
|
||||
FontPixelSize = 0x2009,
|
||||
LastFontProperty = FontPixelSize,
|
||||
FontFeatures = 0x2010, // Note: Same as OldTextUnderlineColor
|
||||
FontVariableAxes = 0x2011,
|
||||
LastFontProperty = FontVariableAxes,
|
||||
|
||||
TextUnderlineColor = 0x2020,
|
||||
TextVerticalAlignment = 0x2021,
|
||||
@ -518,6 +521,11 @@ public:
|
||||
return static_cast<QFont::HintingPreference>(intProperty(FontHintingPreference));
|
||||
}
|
||||
|
||||
void setFontFeatures(const QHash<QFont::Tag, quint32> &fontFeatures);
|
||||
QHash<QFont::Tag, quint32> fontFeatures() const;
|
||||
void setFontVariableAxes(const QHash<QFont::Tag, float> &fontVariableAxes);
|
||||
QHash<QFont::Tag, float> fontVariableAxes() const;
|
||||
|
||||
inline void setFontKerning(bool enable)
|
||||
{ setProperty(FontKerning, enable); }
|
||||
inline bool fontKerning() const
|
||||
|
@ -301,6 +301,7 @@ static constexpr int NColorRoles[] = {
|
||||
QPalette::Accent + 1, // Qt_6_6
|
||||
QPalette::Accent + 1, // Qt_6_7
|
||||
QPalette::Accent + 1, // Qt_6_10
|
||||
QPalette::Accent + 1, // Qt_6_11
|
||||
};
|
||||
|
||||
// +1, because we start from "No Version"
|
||||
|
@ -45,6 +45,8 @@ private slots:
|
||||
void setFont_collection_data();
|
||||
void setFont_collection();
|
||||
void clearCollection();
|
||||
void setFontFeatures();
|
||||
void setFontVariableAxes();
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
void dataStreamCompatibility();
|
||||
@ -667,6 +669,89 @@ void tst_QTextFormat::clearCollection()
|
||||
QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont
|
||||
}
|
||||
|
||||
void tst_QTextFormat::setFontFeatures()
|
||||
{
|
||||
{
|
||||
QFont font;
|
||||
font.setFeature("abcd", 1234);
|
||||
font.setFeature("efgh", 5678);
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setFont(font);
|
||||
|
||||
QFont resolvedFont = format.font();
|
||||
QCOMPARE(resolvedFont.featureTags().size(), 2);
|
||||
QCOMPARE(resolvedFont.featureValue("abcd"), 1234);
|
||||
QCOMPARE(resolvedFont.featureValue("efgh"), 5678);
|
||||
|
||||
QHash<QFont::Tag, quint32> features = format.fontFeatures();
|
||||
QCOMPARE(features.size(), 2);
|
||||
QCOMPARE(features.value("abcd"), 1234);
|
||||
QCOMPARE(features.value("efgh"), 5678);
|
||||
}
|
||||
|
||||
{
|
||||
QTextCharFormat format;
|
||||
|
||||
QHash<QFont::Tag, quint32> features;
|
||||
features.insert("abcd", 4321);
|
||||
features.insert("efgh", 8765);
|
||||
format.setFontFeatures(features);
|
||||
|
||||
QFont resolvedFont = format.font();
|
||||
QCOMPARE(resolvedFont.featureTags().size(), 2);
|
||||
QCOMPARE(resolvedFont.featureValue("abcd"), 4321);
|
||||
QCOMPARE(resolvedFont.featureValue("efgh"), 8765);
|
||||
|
||||
features = format.fontFeatures();
|
||||
QCOMPARE(features.size(), 2);
|
||||
QCOMPARE(features.value("abcd"), 4321);
|
||||
QCOMPARE(features.value("efgh"), 8765);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTextFormat::setFontVariableAxes()
|
||||
{
|
||||
{
|
||||
QFont font;
|
||||
font.setVariableAxis("abcd", 12.25);
|
||||
font.setVariableAxis("efgh", 13.25);
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setFont(font);
|
||||
|
||||
QFont resolvedFont = format.font();
|
||||
QCOMPARE(resolvedFont.variableAxisTags().size(), 2);
|
||||
QCOMPARE(resolvedFont.variableAxisValue("abcd"), 12.25);
|
||||
QCOMPARE(resolvedFont.variableAxisValue("efgh"), 13.25);
|
||||
|
||||
QHash<QFont::Tag, float> axes = format.fontVariableAxes();
|
||||
QCOMPARE(axes.size(), 2);
|
||||
QCOMPARE(axes.value("abcd"), 12.25);
|
||||
QCOMPARE(axes.value("efgh"), 13.25);
|
||||
}
|
||||
|
||||
{
|
||||
QTextCharFormat format;
|
||||
|
||||
QHash<QFont::Tag, float> axes;
|
||||
axes.insert("abcd", 12.25);
|
||||
axes.insert("efgh", 13.25);
|
||||
format.setFontVariableAxes(axes);
|
||||
|
||||
QFont resolvedFont = format.font();
|
||||
QCOMPARE(resolvedFont.variableAxisTags().size(), 2);
|
||||
QCOMPARE(resolvedFont.variableAxisValue("abcd"), 12.25);
|
||||
QCOMPARE(resolvedFont.variableAxisValue("efgh"), 13.25);
|
||||
|
||||
axes = format.fontVariableAxes();
|
||||
QCOMPARE(axes.size(), 2);
|
||||
QCOMPARE(axes.value("abcd"), 12.25);
|
||||
QCOMPARE(axes.value("efgh"), 13.25);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
void tst_QTextFormat::dataStreamCompatibility()
|
||||
{
|
||||
@ -795,6 +880,73 @@ void tst_QTextFormat::dataStreamCompatibility()
|
||||
}
|
||||
}
|
||||
|
||||
// Don't mix up FontFeatures and OldTextUnderlineColor
|
||||
memory.clear();
|
||||
{
|
||||
{
|
||||
QBuffer buffer(&memory);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
|
||||
QFont font;
|
||||
font.setFeature("abcd", 1234);
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setFont(font);
|
||||
|
||||
QDataStream stream(&buffer);
|
||||
|
||||
stream << format;
|
||||
}
|
||||
|
||||
{
|
||||
QBuffer buffer(&memory);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
QDataStream stream(&buffer);
|
||||
|
||||
QTextFormat other;
|
||||
stream >> other;
|
||||
|
||||
QMap<int, QVariant> properties = other.properties();
|
||||
QVERIFY(properties.contains(QTextFormat::FontFeatures));
|
||||
|
||||
auto features = other.property(QTextFormat::FontFeatures).value<QHash<QFont::Tag, quint32>>();
|
||||
QCOMPARE(features.value("abcd"), 1234);
|
||||
}
|
||||
}
|
||||
|
||||
memory.clear();
|
||||
{
|
||||
{
|
||||
QBuffer buffer(&memory);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
|
||||
QFont font;
|
||||
font.setFeature("abcd", 1234);
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setFont(font);
|
||||
|
||||
QDataStream stream(&buffer);
|
||||
stream.setVersion(QDataStream::Qt_5_15);
|
||||
|
||||
stream << format;
|
||||
}
|
||||
|
||||
{
|
||||
QBuffer buffer(&memory);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
QDataStream stream(&buffer);
|
||||
stream.setVersion(QDataStream::Qt_5_15);
|
||||
|
||||
QTextFormat other;
|
||||
stream >> other;
|
||||
QMap<int, QVariant> properties = other.properties();
|
||||
QVERIFY(!properties.contains(QTextFormat::FontFeatures));
|
||||
QVERIFY(!properties.contains(QTextFormat::OldTextUnderlineColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // QT_NO_DATASTREAM
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user