diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 11 | ||||
-rw-r--r-- | src/gui/text/qfont.cpp | 67 | ||||
-rw-r--r-- | src/gui/text/qfont.h | 6 | ||||
-rw-r--r-- | src/gui/text/qfont_p.h | 4 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 54 | ||||
-rw-r--r-- | src/gui/text/qfontengine.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 23 | ||||
-rw-r--r-- | src/gui/text/qtextformat.h | 6 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 3 |
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; |