summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qcssparser.cpp11
-rw-r--r--src/gui/text/qfont.cpp67
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/text/qfont_p.h4
-rw-r--r--src/gui/text/qfontdatabase.cpp54
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qtextformat.cpp23
-rw-r--r--src/gui/text/qtextformat.h6
-rw-r--r--src/gui/text/qtexthtmlparser.cpp3
9 files changed, 143 insertions, 33 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 8e317d5b97..91fa40eddf 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1200,11 +1200,13 @@ static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *font, int start = 0)
{
QString family;
+ QStringList families;
bool shouldAddSpace = false;
for (int i = start; i < values.count(); ++i) {
const QCss::Value &v = values.at(i);
if (v.type == Value::TermOperatorComma) {
- family += QLatin1Char(',');
+ families << family;
+ family.clear();
shouldAddSpace = false;
continue;
}
@@ -1216,9 +1218,12 @@ static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *f
family += str;
shouldAddSpace = true;
}
- if (family.isEmpty())
+ if (!family.isEmpty())
+ families << family;
+ if (families.isEmpty())
return false;
- font->setFamily(family);
+ font->setFamily(families.at(0));
+ font->setFamilies(families);
return true;
}
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index a23ef95fde..258a9ba675 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -116,7 +116,17 @@ bool QFontDef::exactMatch(const QFontDef &other) const
if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
return false;
+ if (families.size() != other.families.size())
+ return false;
+
QString this_family, this_foundry, other_family, other_foundry;
+ for (int i = 0; i < families.size(); ++i) {
+ QFontDatabase::parseFontName(families.at(i), this_foundry, this_family);
+ QFontDatabase::parseFontName(other.families.at(i), other_foundry, other_family);
+ if (this_family != other_family || this_foundry != other_foundry)
+ return false;
+ }
+
QFontDatabase::parseFontName(family, this_foundry, this_family);
QFontDatabase::parseFontName(other.family, other_foundry, other_family);
@@ -261,6 +271,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::FamilyResolved))
request.family = other->request.family;
+ if (!(mask & QFont::FamiliesResolved))
+ request.families = other->request.families;
+
if (! (mask & QFont::StyleNameResolved))
request.styleName = other->request.styleName;
@@ -424,7 +437,8 @@ QFontEngineData::~QFontEngineData()
\target fontmatching
The font matching algorithm works as follows:
\list 1
- \li If the specified font family exists and can be used to represent
+ \li The specified font families (set by setFamilies()) are searched for.
+ \li If not found, then if set the specified font family exists and can be used to represent
the writing system in use, it will be selected.
\li If not, a replacement font that supports the writing system is
selected. The font matching algorithm will try to find the
@@ -506,6 +520,7 @@ QFontEngineData::~QFontEngineData()
individually and then considered resolved.
\value FamilyResolved
+ \value FamiliesResolved
\value SizeResolved
\value StyleHintResolved
\value StyleStrategyResolved
@@ -1691,6 +1706,7 @@ bool QFont::operator<(const QFont &f) const
if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
+ if (r1.families != r2.families) return r1.families < r2.families;
if (r1.family != r2.family) return r1.family < r2.family;
if (f.d->capital != d->capital) return f.d->capital < d->capital;
@@ -2192,6 +2208,48 @@ QString QFont::lastResortFont() const
}
#endif
+/*!
+ \since 5.13
+
+ Returns the requested font family names, i.e. the names set in the last
+ setFamilies() call or via the constructor. Otherwise it returns an
+ empty list.
+
+ \sa setFamily(), setFamilies(), family(), substitutes(), substitute()
+*/
+
+QStringList QFont::families() const
+{
+ return d->request.families;
+}
+
+/*!
+ \since 5.13
+
+ Sets the list of family names for the font. The names are case
+ insensitive and may include a foundry name. The first family in
+ \a families will be set as the main family for the font.
+
+ Each family name entry in \a families may optionally also include a
+ foundry name, e.g. "Helvetica [Cronyx]". If the family is
+ available from more than one foundry and the foundry isn't
+ specified, an arbitrary foundry is chosen. If the family isn't
+ available a family will be set using the \l{QFont}{font matching}
+ algorithm.
+
+ \sa family(), families(), setFamily(), setStyleHint(), QFontInfo
+*/
+
+void QFont::setFamilies(const QStringList &families)
+{
+ if ((resolve_mask & QFont::FamiliesResolved) && d->request.families == families)
+ return;
+ detach();
+ d->request.families = families;
+ resolve_mask |= QFont::FamiliesResolved;
+}
+
+
/*****************************************************************************
QFont stream functions
*****************************************************************************/
@@ -2256,6 +2314,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font)
s << (quint8)font.d->request.hintingPreference;
if (s.version() >= QDataStream::Qt_5_6)
s << (quint8)font.d->capital;
+ if (s.version() >= QDataStream::Qt_5_13)
+ s << font.d->request.families;
return s;
}
@@ -2351,6 +2411,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
s >> value;
font.d->capital = QFont::Capitalization(value);
}
+ if (s.version() >= QDataStream::Qt_5_13) {
+ QStringList value;
+ s >> value;
+ font.d->request.families = value;
+ }
return s;
}
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index a94586166e..1fe450e002 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -164,7 +164,8 @@ public:
WordSpacingResolved = 0x4000,
HintingPreferenceResolved = 0x8000,
StyleNameResolved = 0x10000,
- AllPropertiesResolved = 0x1ffff
+ FamiliesResolved = 0x20000,
+ AllPropertiesResolved = 0x3ffff
};
QFont();
@@ -179,6 +180,9 @@ public:
QString family() const;
void setFamily(const QString &);
+ QStringList families() const;
+ void setFamilies(const QStringList &);
+
QString styleName() const;
void setStyleName(const QString &);
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 350ba7ce3c..09c18de5a6 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -78,6 +78,7 @@ struct QFontDef
}
QString family;
+ QStringList families;
QString styleName;
QStringList fallBackFamilies;
@@ -109,6 +110,7 @@ struct QFontDef
&& styleStrategy == other.styleStrategy
&& ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
&& family == other.family
+ && families == other.families
&& styleName == other.styleName
&& hintingPreference == other.hintingPreference
;
@@ -122,6 +124,7 @@ struct QFontDef
if (styleHint != other.styleHint) return styleHint < other.styleHint;
if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
if (family != other.family) return family < other.family;
+ if (families != other.families) return families < other.families;
if (styleName != other.styleName)
return styleName < other.styleName;
if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
@@ -144,6 +147,7 @@ inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
^ qHash(fd.ignorePitch)
^ qHash(fd.fixedPitch)
^ qHash(fd.family, seed)
+ ^ qHash(fd.families, seed)
^ qHash(fd.styleName)
^ qHash(fd.hintingPreference)
;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 196eebb353..42e7871214 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -696,20 +696,20 @@ static QStringList familyList(const QFontDef &req)
{
// list of families to try
QStringList family_list;
- if (req.family.isEmpty())
- return family_list;
- const auto list = req.family.splitRef(QLatin1Char(','));
- const int numFamilies = list.size();
- family_list.reserve(numFamilies);
- for (int i = 0; i < numFamilies; ++i) {
- QStringRef str = list.at(i).trimmed();
- if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
- || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
- str = str.mid(1, str.length() - 2);
- family_list << str.toString();
+ family_list << req.families;
+ if (!req.family.isEmpty()) {
+ const auto list = req.family.splitRef(QLatin1Char(','));
+ const int numFamilies = list.size();
+ family_list.reserve(numFamilies);
+ for (int i = 0; i < numFamilies; ++i) {
+ QStringRef str = list.at(i).trimmed();
+ if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
+ || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
+ str = str.mid(1, str.length() - 2);
+ family_list << str.toString();
+ }
}
-
// append the substitute list for each family in family_list
for (int i = 0, size = family_list.size(); i < size; ++i)
family_list += QFont::substitutes(family_list.at(i));
@@ -2688,9 +2688,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
QString family_name, foundry_name;
-
- parseFontName(request.family, foundry_name, family_name);
-
+ const QString requestFamily = request.families.size() > 0 ? request.families.at(0) : request.family;
+ parseFontName(requestFamily, foundry_name, family_name);
QtFontDesc desc;
QList<int> blackListed;
int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
@@ -2703,8 +2702,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
// Don't pass empty family names to the platform font database, since it will then invoke its own matching
// and we will be out of sync with the matched font.
- if (fontDef.family.isEmpty())
- fontDef.family = desc.family->name;
+ if (fontDef.families.isEmpty() && fontDef.family.isEmpty())
+ fontDef.families = QStringList(desc.family->name);
engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
@@ -2717,13 +2716,13 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
if (!engine) {
- if (!request.family.isEmpty()) {
+ if (!requestFamily.isEmpty()) {
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
QStringList fallbacks = request.fallBackFamilies
- + fallbacksForFamily(request.family,
+ + fallbacksForFamily(requestFamily,
QFont::Style(request.style),
styleHint,
QChar::Script(script));
@@ -2741,7 +2740,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
index = match(multi ? QChar::Script_Common : script, def, def.family, QLatin1String(""), &desc, blackListed);
if (index >= 0) {
QFontDef loadDef = def;
- if (loadDef.family.isEmpty())
+ if (loadDef.families.isEmpty() && loadDef.family.isEmpty())
loadDef.family = desc.family->name;
engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
if (engine)
@@ -2782,7 +2781,10 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// look for the requested font in the engine data cache
// note: fallBackFamilies are not respected in the EngineData cache key;
// join them with the primary selection family to avoid cache misses
- req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.family.isEmpty())
+ req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.families.isEmpty())
+ req.families = fallBackFamilies;
d->engineData = fontCache->findEngineData(req);
if (!d->engineData) {
@@ -2803,14 +2805,14 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
- req.family = req.fallBackFamilies.takeFirst();
+ req.families = QStringList(req.fallBackFamilies.takeFirst());
// list of families to try
QStringList family_list;
- if (!req.family.isEmpty()) {
+ if (!req.families.isEmpty()) {
// Add primary selection
- family_list << req.family;
+ family_list << req.families.at(0);
// add the default family
QString defaultFamily = QGuiApplication::font().family();
@@ -2824,11 +2826,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
for (; !fe && it != end; ++it) {
- req.family = *it;
+ req.families = QStringList(*it);
fe = QFontDatabase::findFont(req, script);
if (fe) {
- if (fe->type() == QFontEngine::Box && !req.family.isEmpty()) {
+ if (fe->type() == QFontEngine::Box && !req.families.isEmpty()) {
if (fe->ref.load() == 0)
delete fe;
fe = 0;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 9b0b0ec0d5..b06b64ca63 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1842,7 +1842,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
{
QFontDef request(fontDef);
request.styleStrategy |= QFont::NoFontMerging;
- request.family = fallbackFamilyAt(at - 1);
+ request.families = QStringList(fallbackFamilyAt(at - 1));
// At this point, the main script of the text has already been considered
// when fetching the list of fallback families from the database, and the
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 4957da1908..18de8408b5 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -361,6 +361,9 @@ void QTextFormatPrivate::recalcFont() const
case QTextFormat::FontFamily:
f.setFamily(props.at(i).value.toString());
break;
+ case QTextFormat::FontFamilies:
+ f.setFamilies(props.at(i).value.toStringList());
+ break;
case QTextFormat::FontPointSize:
f.setPointSizeF(props.at(i).value.toReal());
break;
@@ -562,6 +565,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
Character properties
\value FontFamily
+ \value FontFamilies
\value FontPointSize
\value FontPixelSize
\value FontSizeAdjustment Specifies the change in size given to the fontsize already set using
@@ -1390,7 +1394,23 @@ QTextCharFormat::QTextCharFormat(const QTextFormat &fmt)
\sa font()
*/
+/*!
+ \fn void QTextCharFormat::setFontFamilies(const QStringList &families)
+ \since 5.13
+
+ Sets the text format's font \a families.
+
+ \sa setFont()
+*/
+
+/*!
+ \fn QStringList QTextCharFormat::fontFamilies() const
+ \since 5.13
+
+ Returns the text format's font families.
+ \sa font()
+*/
/*!
\fn void QTextCharFormat::setFontPointSize(qreal size)
@@ -1919,6 +1939,9 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi
if (mask & QFont::FamilyResolved)
setFontFamily(font.family());
+ if (mask & QFont::FamiliesResolved)
+ setFontFamilies(font.families());
+
if (mask & QFont::SizeResolved) {
const qreal pointSize = font.pointSizeF();
if (pointSize > 0) {
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index a8e573d5a4..d27d2e7f17 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -188,6 +188,7 @@ public:
FontStyleStrategy = 0x1FE4,
FontKerning = 0x1FE5,
FontHintingPreference = 0x1FE6,
+ FontFamilies = 0x1FE7,
FontFamily = 0x2000,
FontPointSize = 0x2001,
FontSizeAdjustment = 0x2002,
@@ -428,6 +429,11 @@ public:
inline QString fontFamily() const
{ return stringProperty(FontFamily); }
+ inline void setFontFamilies(const QStringList &families)
+ { setProperty(FontFamilies, QVariant(families)); }
+ inline QVariant fontFamilies() const
+ { return property(FontFamilies); }
+
inline void setFontPointSize(qreal size)
{ setProperty(FontPointSize, size); }
inline qreal fontPointSize() const
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 4be800b251..9d2a5d553a 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -862,7 +862,8 @@ QString QTextHtmlParser::parseWord()
++pos;
while (pos < len) {
QChar c = txt.at(pos++);
- if (c == QLatin1Char('\''))
+ // Allow for escaped single quotes as they may be part of the string
+ if (c == QLatin1Char('\'') && (txt.length() > 1 && txt.at(pos - 2) != QLatin1Char('\\')))
break;
else
word += c;