summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qfont.cpp')
-rw-r--r--src/gui/text/qfont.cpp113
1 files changed, 60 insertions, 53 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 2b2f2a27fcd..ba49d538c2c 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -31,6 +31,7 @@
#include <QtCore/QMutexLocker>
#include <QtCore/QMutex>
+#include <algorithm>
#include <array>
// #define QFONTCACHE_DEBUG
@@ -1853,35 +1854,13 @@ bool QFont::operator<(const QFont &f) const
int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
if (f1attrs != f2attrs) return f1attrs < f2attrs;
- if (d->features.size() != f.d->features.size())
- return f.d->features.size() < d->features.size();
-
- {
- auto it = d->features.constBegin();
- auto jt = f.d->features.constBegin();
- for (; it != d->features.constEnd(); ++it, ++jt) {
- if (it.key() != jt.key())
- return jt.key() < it.key();
- if (it.value() != jt.value())
- return jt.value() < it.value();
- }
+ if (d->features != f.d->features) {
+ return std::lexicographical_compare(f.d->features.keyValueBegin(), f.d->features.keyValueEnd(),
+ d->features.keyValueBegin(), d->features.keyValueEnd());
}
- if (r1.variableAxisValues.size() != r2.variableAxisValues.size())
- return r1.variableAxisValues.size() < r2.variableAxisValues.size();
-
- {
- auto it = r1.variableAxisValues.constBegin();
- auto jt = r2.variableAxisValues.constBegin();
- for (; it != r1.variableAxisValues.constEnd(); ++it, ++jt) {
- if (it.key() != jt.key())
- return jt.key() < it.key();
- if (it.value() != jt.value())
- return jt.value() < it.value();
- }
- }
-
- return false;
+ return std::lexicographical_compare(r1.variableAxisValues.keyValueBegin(), r1.variableAxisValues.keyValueEnd(),
+ r2.variableAxisValues.keyValueBegin(), r2.variableAxisValues.keyValueEnd());
}
@@ -2170,6 +2149,7 @@ QString QFont::key() const
\li Style strategy
\li Font style
\li Font features
+ \li Variable axes
\endlist
\sa fromString()
@@ -2195,12 +2175,12 @@ QString QFont::toString() const
QString::number((int)styleStrategy()) + comma +
styleName();
- QMap<Tag, quint32> sortedFeatures;
+ fontDescription += comma + QString::number(d->features.size());
for (const auto &[tag, value] : std::as_const(d->features).asKeyValueRange())
- sortedFeatures.insert(tag, value);
+ fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
- fontDescription += comma + QString::number(sortedFeatures.size());
- for (const auto &[tag, value] : std::as_const(sortedFeatures).asKeyValueRange())
+ fontDescription += comma + QString::number(d->request.variableAxisValues.size());
+ for (const auto &[tag, value] : std::as_const(d->request.variableAxisValues).asKeyValueRange())
fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
return fontDescription;
@@ -2216,7 +2196,7 @@ size_t qHash(const QFont &font, size_t seed) noexcept
return qHash(QFontPrivate::get(font)->request, seed);
}
-static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStringView view)
+static std::optional<std::pair<QFont::Tag, quint32>> fontFeatureFromString(QStringView view)
{
const int separator = view.indexOf(u'=');
if (separator == -1)
@@ -2234,6 +2214,24 @@ static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStri
return std::make_pair(*tag, value);
}
+static std::optional<std::pair<QFont::Tag, float>> variableAxisFromString(QStringView view)
+{
+ const int separator = view.indexOf(u'=');
+ if (separator == -1)
+ return std::nullopt;
+
+ const std::optional<QFont::Tag> tag = QFont::Tag::fromString(view.sliced(0, separator));
+ if (!tag)
+ return std::nullopt;
+
+ bool valueOk = false;
+ const float value = view.sliced(separator + 1).toFloat(&valueOk);
+ if (!valueOk)
+ return std::nullopt;
+
+ return std::make_pair(*tag, value);
+}
+
/*!
Sets this font to match the description \a descrip. The description
is a comma-separated list of the font attributes, as returned by
@@ -2246,8 +2244,7 @@ bool QFont::fromString(const QString &descrip)
const auto sr = QStringView(descrip).trimmed();
const auto l = sr.split(u',');
const int count = l.size();
- if (!count || (count > 2 && count < 9) || count == 9 ||
- l.first().isEmpty()) {
+ if (!count || (count > 2 && count < 10) || l.first().isEmpty()) {
qWarning("QFont::fromString: Invalid description '%s'",
descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
return false;
@@ -2256,14 +2253,8 @@ bool QFont::fromString(const QString &descrip)
setFamily(l[0].toString());
if (count > 1 && l[1].toDouble() > 0.0)
setPointSizeF(l[1].toDouble());
- if (count == 9) {
- setStyleHint((StyleHint) l[2].toInt());
- setWeight(QFont::Weight(l[3].toInt()));
- setItalic(l[4].toInt());
- setUnderline(l[5].toInt());
- setStrikeOut(l[6].toInt());
- setFixedPitch(l[7].toInt());
- } else if (count >= 10) {
+
+ if (count >= 10) {
if (l[2].toInt() > 0)
setPixelSize(l[2].toInt());
setStyleHint((StyleHint) l[3].toInt());
@@ -2275,6 +2266,8 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[6].toInt());
setStrikeOut(l[7].toInt());
setFixedPitch(l[8].toInt());
+ if (!d->request.fixedPitch) // assume 'false' fixedPitch equals default
+ d->request.ignorePitch = true;
if (count >= 16) {
setCapitalization((Capitalization)l[10].toInt());
setLetterSpacing((SpacingType)l[11].toInt(), l[12].toDouble());
@@ -2291,19 +2284,33 @@ bool QFont::fromString(const QString &descrip)
d->request.styleName.clear();
clearFeatures();
- if (count >= 18) {
- const int featureCount = l[17].toInt();
- if (count >= featureCount + 18) {
- for (int i = 0; i < featureCount; ++i) {
- if (const auto feature = tagAndValueFromString(l[18 + i]))
- setFeature(feature->first, feature->second);
- }
- }
+ clearVariableAxes();
+
+ int position = 17;
+ if (position >= count)
+ return true;
+
+ const int featureCount = l[position++].toInt();
+ if (position + featureCount > count)
+ return true;
+
+ for (int i = 0; i < featureCount; ++i) {
+ if (const auto feature = fontFeatureFromString(l[position++]))
+ setFeature(feature->first, feature->second);
}
- }
- if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
- d->request.ignorePitch = true;
+ if (position >= count)
+ return true;
+
+ const int variableAxisCount = l[position++].toInt();
+ if (position + variableAxisCount > count)
+ return true;
+
+ for (int i = 0; i < variableAxisCount; ++i) {
+ if (const auto axis = variableAxisFromString(l[position++]))
+ setVariableAxis(axis->first, axis->second);
+ }
+ }
return true;
}