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.cpp194
1 files changed, 185 insertions, 9 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index a23ef95fde..164a2f60ab 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
@@ -547,14 +562,25 @@ QFontEngineData::~QFontEngineData()
\since 5.2
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
+ \obsolete
Constructs a font from \a font for use on the paint device \a pd.
*/
QFont::QFont(const QFont &font, QPaintDevice *pd)
+ : QFont(font, static_cast<const QPaintDevice*>(pd))
+{}
+#endif
+
+/*!
+ \since 5.13
+ Constructs a font from \a font for use on the paint device \a pd.
+*/
+QFont::QFont(const QFont &font, const QPaintDevice *pd)
: resolve_mask(font.resolve_mask)
{
- Q_ASSERT(pd != 0);
- int dpi = pd->logicalDpiY();
+ Q_ASSERT(pd);
+ const int dpi = pd->logicalDpiY();
const int screen = 0;
if (font.d->dpi != dpi || font.d->screen != screen ) {
d = new QFontPrivate(*font.d);
@@ -1261,7 +1287,7 @@ QFont::StyleStrategy QFont::styleStrategy() const
/*!
Returns the StyleHint.
- The style hint affects the \l{#fontmatching}{font matching algorithm}.
+ The style hint affects the \l{QFont#fontmatching}{font matching algorithm}.
See \l QFont::StyleHint for the list of available hints.
\sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()
@@ -1691,6 +1717,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;
@@ -2056,7 +2083,7 @@ QString QFont::toString() const
\relates QFont
\since 5.3
*/
-uint qHash(const QFont &font, uint seed) Q_DECL_NOTHROW
+uint qHash(const QFont &font, uint seed) noexcept
{
return qHash(QFontPrivate::get(font)->request, seed);
}
@@ -2153,7 +2180,7 @@ void QFont::cacheStatistics()
*/
QString QFont::lastResortFamily() const
{
- return QString::fromLatin1("helvetica");
+ return QStringLiteral("helvetica");
}
#endif
@@ -2188,10 +2215,55 @@ QString QFont::defaultFamily() const
*/
QString QFont::lastResortFont() const
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
return lastResortFamily();
+QT_WARNING_POP
}
#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 +2328,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 +2425,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;
}
@@ -2874,9 +2953,9 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
data.timestamp = ++current_timestamp;
if (insertMulti)
- engineCache.insertMulti(key, data);
- else
engineCache.insert(key, data);
+ else
+ engineCache.replace(key, data);
// only increase the cost if this is the first time we insert the engine
if (++engineCacheCount[engine] == 1)
increaseCost(engine->cache_cost);
@@ -3085,7 +3164,104 @@ void QFontCache::decreaseCache()
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug stream, const QFont &font)
{
- return stream << "QFont(" << font.toString() << ')';
+ QDebugStateSaver saver(stream);
+ stream.nospace().noquote();
+ stream << "QFont(";
+
+ if (stream.verbosity() == QDebug::DefaultVerbosity) {
+ stream << font.toString() << ")";
+ return stream;
+ }
+
+ QString fontDescription;
+ QDebug debug(&fontDescription);
+ debug.nospace();
+
+ QFontPrivate priv;
+ const QFont defaultFont(&priv);
+
+ for (int property = QFont::FamilyResolved; property < QFont::AllPropertiesResolved; property <<= 1) {
+ const bool resolved = (font.resolve_mask & property) != 0;
+ if (!resolved && stream.verbosity() == QDebug::MinimumVerbosity)
+ continue;
+
+ #define QFONT_DEBUG_SKIP_DEFAULT(prop) \
+ if ((font.prop() == defaultFont.prop()) && stream.verbosity() == 1) \
+ continue;
+
+ QDebugStateSaver saver(debug);
+
+ switch (property) {
+ case QFont::FamilyResolved:
+ debug << font.family(); break;
+ case QFont::SizeResolved:
+ if (font.pointSizeF() >= 0)
+ debug << font.pointSizeF() << "pt";
+ else if (font.pixelSize() >= 0)
+ debug << font.pixelSize() << "px";
+ else
+ Q_UNREACHABLE();
+ break;
+ case QFont::StyleHintResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleHint);
+ debug.verbosity(1) << font.styleHint(); break;
+ case QFont::StyleStrategyResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleStrategy);
+ debug.verbosity(1) << font.styleStrategy(); break;
+ case QFont::WeightResolved:
+ debug.verbosity(1) << QFont::Weight(font.weight()); break;
+ case QFont::StyleResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(style);
+ debug.verbosity(0) << font.style(); break;
+ case QFont::UnderlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(underline);
+ debug << "underline=" << font.underline(); break;
+ case QFont::OverlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(overline);
+ debug << "overline=" << font.overline(); break;
+ case QFont::StrikeOutResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(strikeOut);
+ debug << "strikeOut=" << font.strikeOut(); break;
+ case QFont::FixedPitchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(fixedPitch);
+ debug << "fixedPitch=" << font.fixedPitch(); break;
+ case QFont::StretchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(stretch);
+ debug.verbosity(0) << QFont::Stretch(font.stretch()); break;
+ case QFont::KerningResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(kerning);
+ debug << "kerning=" << font.kerning(); break;
+ case QFont::CapitalizationResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(capitalization);
+ debug.verbosity(0) << font.capitalization(); break;
+ case QFont::LetterSpacingResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(letterSpacing);
+ debug << "letterSpacing=" << font.letterSpacing();
+ debug.verbosity(0) << " (" << font.letterSpacingType() << ")";
+ break;
+ case QFont::HintingPreferenceResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(hintingPreference);
+ debug.verbosity(0) << font.hintingPreference(); break;
+ case QFont::StyleNameResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleName);
+ debug << "styleName=" << font.styleName(); break;
+ default:
+ continue;
+ };
+
+ #undef QFONT_DEBUG_SKIP_DEFAULT
+
+ debug << ", ";
+ }
+
+ if (stream.verbosity() > QDebug::MinimumVerbosity)
+ debug.verbosity(0) << "resolveMask=" << QFlags<QFont::ResolveProperties>(font.resolve_mask);
+ else
+ fontDescription.chop(2); // Last ', '
+
+ stream << fontDescription << ')';
+
+ return stream;
}
#endif