summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qcssparser.cpp1
-rw-r--r--src/gui/text/qcssparser_p.h1
-rw-r--r--src/gui/text/qdistancefield.cpp7
-rw-r--r--src/gui/text/qdistancefield_p.h1
-rw-r--r--src/gui/text/qfont.cpp36
-rw-r--r--src/gui/text/qfontdatabase.cpp34
-rw-r--r--src/gui/text/qglyphrun.cpp2
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp2
-rw-r--r--src/gui/text/qrawfont_p.h2
-rw-r--r--src/gui/text/qstatictext.cpp4
-rw-r--r--src/gui/text/qtextdocument.cpp51
-rw-r--r--src/gui/text/qtextdocument.h2
-rw-r--r--src/gui/text/qtextdocument_p.h2
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp12
-rw-r--r--src/gui/text/qtexthtmlparser.cpp53
-rw-r--r--src/gui/text/qtexthtmlparser_p.h1
-rw-r--r--src/gui/text/qtextmarkdownimporter.cpp2
-rw-r--r--src/gui/text/qtextmarkdownwriter.cpp5
-rw-r--r--src/gui/text/qtextmarkdownwriter_p.h5
19 files changed, 163 insertions, 60 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index dc7e128bcd..b5489c7ed9 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -67,6 +67,7 @@ struct QCssKnownValue
static const QCssKnownValue properties[NumProperties - 1] = {
{ "-qt-background-role", QtBackgroundRole },
{ "-qt-block-indent", QtBlockIndent },
+ { "-qt-fg-texture-cachekey", QtForegroundTextureCacheKey },
{ "-qt-line-height-type", QtLineHeightType },
{ "-qt-list-indent", QtListIndent },
{ "-qt-list-number-prefix", QtListNumberPrefix },
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 62578f75e5..b0fa4be682 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -196,6 +196,7 @@ enum Property {
LineHeight,
QtLineHeightType,
FontKerning,
+ QtForegroundTextureCacheKey,
NumProperties
};
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index 5967c8d3de..17824a5ba1 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -782,7 +782,7 @@ bool qt_fontHasNarrowOutlines(QFontEngine *fontEngine)
if (glyph != 0)
im = fe->alphaMapForGlyph(glyph, QFixed(), QTransform());
- Q_ASSERT(fe->ref.load() == 0);
+ Q_ASSERT(fe->ref.loadRelaxed() == 0);
delete fe;
return imageHasNarrowOutlines(im);
@@ -899,11 +899,6 @@ QDistanceField::QDistanceField(int width, int height)
{
}
-QDistanceField::QDistanceField(const QDistanceField &other)
-{
- d = other.d;
-}
-
QDistanceField &QDistanceField::operator=(const QDistanceField &)
= default;
diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h
index dc5d5a9a02..d6d8edd85d 100644
--- a/src/gui/text/qdistancefield_p.h
+++ b/src/gui/text/qdistancefield_p.h
@@ -94,7 +94,6 @@ public:
QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution = false);
QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false);
QDistanceField(const QPainterPath &path, glyph_t glyph, bool doubleResolution = false);
- QDistanceField(const QDistanceField &other);
QDistanceField &operator=(const QDistanceField &other);
bool isNull() const;
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 164a2f60ab..97e73f0723 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -208,7 +208,7 @@ QFontPrivate::~QFontPrivate()
scFont = 0;
}
-extern QMutex *qt_fontdatabase_mutex();
+extern QRecursiveMutex *qt_fontdatabase_mutex();
#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
@@ -336,7 +336,7 @@ QFontEngineData::QFontEngineData()
QFontEngineData::~QFontEngineData()
{
- Q_ASSERT(ref.load() == 0);
+ Q_ASSERT(ref.loadRelaxed() == 0);
for (int i = 0; i < QChar::ScriptCount; ++i) {
if (engines[i]) {
if (!engines[i]->ref.deref())
@@ -604,7 +604,7 @@ QFont::QFont(QFontPrivate *data)
*/
void QFont::detach()
{
- if (d->ref.load() == 1) {
+ if (d->ref.loadRelaxed() == 1) {
if (d->engineData && !d->engineData->ref.deref())
delete d->engineData;
d->engineData = 0;
@@ -625,7 +625,7 @@ void QFont::detach()
*/
void QFontPrivate::detachButKeepEngineData(QFont *font)
{
- if (font->d->ref.load() == 1)
+ if (font->d->ref.loadRelaxed() == 1)
return;
QFontEngineData *engineData = font->d->engineData;
@@ -2799,12 +2799,12 @@ void QFontCache::cleanup()
cache->setLocalData(0);
}
-QBasicAtomicInt font_cache_id = Q_BASIC_ATOMIC_INITIALIZER(1);
+static QBasicAtomicInt font_cache_id = Q_BASIC_ATOMIC_INITIALIZER(0);
QFontCache::QFontCache()
: QObject(), total_cost(0), max_cost(min_cost),
current_timestamp(0), fast(false), timer_id(-1),
- m_id(font_cache_id.fetchAndAddRelaxed(1))
+ m_id(font_cache_id.fetchAndAddRelaxed(1) + 1)
{
}
@@ -2833,7 +2833,7 @@ void QFontCache::clear()
delete data;
} else {
FC_DEBUG("QFontCache::clear: engineData %p still has refcount %d",
- data, data->ref.load());
+ data, data->ref.loadRelaxed());
}
++it;
}
@@ -2857,7 +2857,7 @@ void QFontCache::clear()
delete engine;
} else if (cacheCount == 0) {
FC_DEBUG("QFontCache::clear: engine %p still has refcount %d",
- engine, engine->ref.load());
+ engine, engine->ref.loadRelaxed());
}
it.value().data = 0;
}
@@ -2927,7 +2927,7 @@ void QFontCache::updateHitCountAndTimeStamp(Engine &value)
FC_DEBUG("QFontCache: found font engine\n"
" %p: timestamp %4u hits %3u ref %2d/%2d, type %d",
value.data, value.timestamp, value.hits,
- value.data->ref.load(), engineCacheCount.value(value.data),
+ value.data->ref.loadRelaxed(), engineCacheCount.value(value.data),
value.data->type());
}
@@ -2937,7 +2937,7 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
Q_ASSERT(key.multi == (engine->type() == QFontEngine::Multi));
#ifdef QFONTCACHE_DEBUG
- FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load());
+ FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.loadRelaxed());
if (!insertMulti && engineCache.contains(key)) {
FC_DEBUG(" QFontCache already contains engine %p for key=(%g %g %d %d %d)",
engineCache.value(key).data, key.def.pointSize,
@@ -3026,9 +3026,9 @@ void QFontCache::decreaseCache()
EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
end = engineDataCache.constEnd();
for (; it != end; ++it) {
- FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref.load()));
+ FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref.loadRelaxed()));
- if (it.value()->ref.load() != 1)
+ if (it.value()->ref.loadRelaxed() != 1)
in_use_cost += engine_data_cost;
}
}
@@ -3041,10 +3041,10 @@ void QFontCache::decreaseCache()
for (; it != end; ++it) {
FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
it.value().data, it.value().timestamp, it.value().hits,
- it.value().data->ref.load(), engineCacheCount.value(it.value().data),
+ it.value().data->ref.loadRelaxed(), engineCacheCount.value(it.value().data),
it.value().data->cache_cost);
- if (it.value().data->ref.load() != 0)
+ if (it.value().data->ref.loadRelaxed() > engineCacheCount.value(it.value().data))
in_use_cost += it.value().data->cache_cost / engineCacheCount.value(it.value().data);
}
@@ -3093,7 +3093,7 @@ void QFontCache::decreaseCache()
// clean out all unused engine data
EngineDataCache::Iterator it = engineDataCache.begin();
while (it != engineDataCache.end()) {
- if (it.value()->ref.load() == 1) {
+ if (it.value()->ref.loadRelaxed() == 1) {
FC_DEBUG(" %p", it.value());
decreaseCost(sizeof(QFontEngineData));
it.value()->ref.deref();
@@ -3121,7 +3121,7 @@ void QFontCache::decreaseCache()
EngineCache::Iterator jt = end;
for ( ; it != end; ++it) {
- if (it.value().data->ref.load() != engineCacheCount.value(it.value().data))
+ if (it.value().data->ref.loadRelaxed() != engineCacheCount.value(it.value().data))
continue;
if (it.value().timestamp < oldest && it.value().hits <= least_popular) {
@@ -3135,7 +3135,7 @@ void QFontCache::decreaseCache()
if (it != end) {
FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type %d",
it.value().data, it.value().timestamp, it.value().hits,
- it.value().data->ref.load(), engineCacheCount.value(it.value().data),
+ it.value().data->ref.loadRelaxed(), engineCacheCount.value(it.value().data),
it.value().data->type());
QFontEngine *fontEngine = it.value().data;
@@ -3150,7 +3150,7 @@ void QFontCache::decreaseCache()
}
}
// and delete the last occurrence
- Q_ASSERT(fontEngine->ref.load() == 0);
+ Q_ASSERT(fontEngine->ref.loadRelaxed() == 0);
decreaseCost(fontEngine->cache_cost);
delete fontEngine;
engineCacheCount.remove(fontEngine);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 3cbda0facd..ce6bb0c347 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -451,8 +451,7 @@ class QFontDatabasePrivate
public:
QFontDatabasePrivate()
: count(0), families(0),
- fallbacksCache(64),
- reregisterAppFonts(false)
+ fallbacksCache(64)
{ }
~QFontDatabasePrivate() {
@@ -488,7 +487,6 @@ public:
};
QVector<ApplicationFont> applicationFonts;
int addAppFont(const QByteArray &fontData, const QString &fileName);
- bool reregisterAppFonts;
bool isApplicationFont(const QString &fileName);
void invalidate();
@@ -695,7 +693,8 @@ static QStringList familyList(const QFontDef &req)
if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
|| (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
str = str.mid(1, str.length() - 2);
- family_list << str.toString();
+ if (!family_list.contains(str))
+ family_list << str.toString();
}
}
// append the substitute list for each family in family_list
@@ -706,7 +705,7 @@ static QStringList familyList(const QFontDef &req)
}
Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, fontDatabaseMutex)
// used in qguiapplication.cpp
void qt_cleanupFontDatabase()
@@ -718,8 +717,8 @@ void qt_cleanupFontDatabase()
}
}
-// used in qfontengine_x11.cpp
-QMutex *qt_fontdatabase_mutex()
+// used in qfont.cpp
+QRecursiveMutex *qt_fontdatabase_mutex()
{
return fontDatabaseMutex();
}
@@ -896,15 +895,12 @@ static void initializeDb()
QFontDatabasePrivate *db = privateDb();
// init by asking for the platformfontdb for the first time or after invalidation
- if (!db->count)
+ if (!db->count) {
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
-
- if (db->reregisterAppFonts) {
for (int i = 0; i < db->applicationFonts.count(); i++) {
if (!db->applicationFonts.at(i).families.isEmpty())
registerFont(&db->applicationFonts[i]);
}
- db->reregisterAppFonts = false;
}
}
@@ -977,7 +973,7 @@ QFontEngine *loadSingleEngine(int script,
if (!engine->supportsScript(QChar::Script(script))) {
qWarning(" OpenType support missing for \"%s\", script %d",
+ qPrintable(def.family), script);
- if (engine->ref.load() == 0)
+ if (engine->ref.loadRelaxed() == 0)
delete engine;
return 0;
}
@@ -1032,11 +1028,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
- QFontDatabasePrivate *db = privateDb();
-
fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
-
- db->reregisterAppFonts = true;
}
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
@@ -2450,13 +2442,18 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
if (font.fileName.isEmpty() && !fontData.isEmpty())
font.fileName = QLatin1String(":qmemoryfonts/") + QString::number(i);
+ bool wasEmpty = privateDb()->count == 0;
registerFont(&font);
if (font.families.isEmpty())
return -1;
applicationFonts[i] = font;
- invalidate();
+ // If the cache has not yet been populated, we need to reload the application font later
+ if (wasEmpty)
+ invalidate();
+ else
+ emit qApp->fontDatabaseChanged();
return i;
}
@@ -2597,7 +2594,6 @@ bool QFontDatabase::removeApplicationFont(int handle)
db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
- db->reregisterAppFonts = true;
db->invalidate();
return true;
}
@@ -2826,7 +2822,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
fe = QFontDatabase::findFont(req, script);
if (fe) {
if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
- if (fe->ref.load() == 0)
+ if (fe->ref.loadRelaxed() == 0)
delete fe;
fe = 0;
} else {
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index bd44e11dce..3c16c3bf62 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -137,7 +137,7 @@ QGlyphRun::~QGlyphRun()
*/
void QGlyphRun::detach()
{
- if (d->ref.load() != 1)
+ if (d->ref.loadRelaxed() != 1)
d.detach();
}
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 715b00d838..90322b24da 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -235,7 +235,7 @@ QSupportedWritingSystems::~QSupportedWritingSystems()
*/
void QSupportedWritingSystems::detach()
{
- if (d->ref.load() != 1) {
+ if (d->ref.loadRelaxed() != 1) {
QWritingSystemsPrivate *newd = new QWritingSystemsPrivate(d);
if (!d->ref.deref())
delete d;
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index dced165475..03259a94ed 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -87,7 +87,7 @@ public:
~QRawFontPrivate()
{
#ifndef QT_NO_DEBUG
- Q_ASSERT(ref.load() == 0);
+ Q_ASSERT(ref.loadRelaxed() == 0);
#endif
cleanUp();
}
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index dd894f4d32..490e0b6b8f 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -181,7 +181,7 @@ QStaticText::QStaticText(const QStaticText &other)
*/
QStaticText::~QStaticText()
{
- Q_ASSERT(!data || data->ref.load() >= 1);
+ Q_ASSERT(!data || data->ref.loadRelaxed() >= 1);
}
/*!
@@ -189,7 +189,7 @@ QStaticText::~QStaticText()
*/
void QStaticText::detach()
{
- if (data->ref.load() != 1)
+ if (data->ref.loadRelaxed() != 1)
data.detach();
}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 899801ca39..dc34a96918 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1364,6 +1364,8 @@ QTextCursor QTextDocument::find(const QString &subString, int from, FindFlags op
blockOffset = 0;
}
} else {
+ if (blockOffset == block.length() - 1)
+ --blockOffset; // make sure to skip end-of-paragraph character
while (block.isValid()) {
if (findInBlock(block, subString, blockOffset, options, &cursor))
return cursor;
@@ -2304,7 +2306,11 @@ QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode)
if (mode == ExportEntireDocument) {
html += QLatin1String(" style=\"");
- emitFontFamily(defaultCharFormat.fontFamily());
+ QStringList fontFamilies = defaultCharFormat.fontFamilies().toStringList();
+ if (!fontFamilies.isEmpty())
+ emitFontFamily(fontFamilies);
+ else
+ emitFontFamily(defaultCharFormat.fontFamily());
if (defaultCharFormat.hasProperty(QTextFormat::FontPointSize)) {
html += QLatin1String(" font-size:");
@@ -2366,8 +2372,12 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
bool attributesEmitted = false;
{
+ const QStringList families = format.fontFamilies().toStringList();
const QString family = format.fontFamily();
- if (!family.isEmpty() && family != defaultCharFormat.fontFamily()) {
+ if (!families.isEmpty() && families != defaultCharFormat.fontFamilies().toStringList()) {
+ emitFontFamily(families);
+ attributesEmitted = true;
+ } else if (!family.isEmpty() && family != defaultCharFormat.fontFamily()) {
emitFontFamily(family);
attributesEmitted = true;
}
@@ -2468,9 +2478,19 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
if (format.foreground() != defaultCharFormat.foreground()
&& format.foreground().style() != Qt::NoBrush) {
- html += QLatin1String(" color:");
- html += colorValue(format.foreground().color());
- html += QLatin1Char(';');
+ QBrush brush = format.foreground();
+ if (brush.style() == Qt::TexturePattern) {
+ const bool isPixmap = qHasPixmapTexture(brush);
+ const qint64 cacheKey = isPixmap ? brush.texture().cacheKey() : brush.textureImage().cacheKey();
+
+ html += QLatin1String(" -qt-fg-texture-cachekey:");
+ html += QString::number(cacheKey);
+ html += QLatin1String(";");
+ } else {
+ html += QLatin1String(" color:");
+ html += colorValue(brush.color());
+ html += QLatin1Char(';');
+ }
attributesEmitted = true;
}
@@ -2644,6 +2664,27 @@ void QTextHtmlExporter::emitFontFamily(const QString &family)
html += QLatin1Char(';');
}
+void QTextHtmlExporter::emitFontFamily(const QStringList &families)
+{
+ html += QLatin1String(" font-family:");
+
+ bool first = true;
+ for (const QString &family : families) {
+ QLatin1String quote("\'");
+ if (family.contains(QLatin1Char('\'')))
+ quote = QLatin1String("&quot;");
+
+ if (!first)
+ html += QLatin1String(",");
+ else
+ first = false;
+ html += quote;
+ html += family.toHtmlEscaped();
+ html += quote;
+ }
+ html += QLatin1Char(';');
+}
+
void QTextHtmlExporter::emitMargins(const QString &top, const QString &bottom, const QString &left, const QString &right)
{
html += QLatin1String(" margin-top:");
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index edb6bd9310..2fadc40cd2 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -225,6 +225,7 @@ public:
void print(QPagedPaintDevice *printer) const;
enum ResourceType {
+ UnknownResource = 0,
HtmlResource = 1,
ImageResource = 2,
StyleSheetResource = 3,
@@ -232,6 +233,7 @@ public:
UserResource = 100
};
+ Q_ENUM(ResourceType)
QVariant resource(int type, const QUrl &name) const;
void addResource(int type, const QUrl &name, const QVariant &resource);
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index a8e17bfc08..f4e7a25f22 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -357,6 +357,7 @@ public:
void mergeCachedResources(const QTextDocumentPrivate *priv);
+ friend struct QTextHtmlParserNode;
friend class QTextHtmlExporter;
friend class QTextCursor;
};
@@ -396,6 +397,7 @@ private:
void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy);
void emitFontFamily(const QString &family);
+ void emitFontFamily(const QStringList &families);
void emitBackgroundAttribute(const QTextFormat &format);
QString findUrlForImage(const QTextDocument *doc, qint64 cacheKey, bool isPixmap);
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index e5cfa7f46e..a1b21b111b 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -973,8 +973,14 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
if (pageHeight <= 0)
pageHeight = QFIXED_MAX;
- const int tableStartPage = (td->position.y / pageHeight).truncate();
- const int tableEndPage = ((td->position.y + td->size.height) / pageHeight).truncate();
+ QFixed absYPos = td->position.y;
+ QTextFrame *parentFrame = table->parentFrame();
+ while (parentFrame) {
+ absYPos += data(parentFrame)->position.y;
+ parentFrame = parentFrame->parentFrame();
+ }
+ const int tableStartPage = (absYPos / pageHeight).truncate();
+ const int tableEndPage = ((absYPos + td->size.height) / pageHeight).truncate();
qreal border = td->border.toReal();
drawFrameDecoration(painter, frame, fd, context.clip, frameRect);
@@ -1614,7 +1620,7 @@ QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom
for (int i = 0; i < children.count(); ++i) {
QTextFrame *frame = children.at(i);
QTextTableCell cell = table->cellAt(frame->firstPosition());
- td->childFrameMap.insertMulti(cell.row() + cell.column() * rows, frame);
+ td->childFrameMap.insert(cell.row() + cell.column() * rows, frame);
}
}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 642f0893b4..1ee317d27c 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1335,6 +1335,17 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
default: break;
}
break;
+
+ case QCss::QtForegroundTextureCacheKey:
+ {
+ if (resourceProvider != nullptr && resourceProvider->docHandle() != nullptr) {
+ bool ok;
+ qint64 searchKey = decl.d->values.first().variant.toLongLong(&ok);
+ if (ok)
+ applyForegroundImage(searchKey, resourceProvider);
+ }
+ break;
+ }
default: break;
}
}
@@ -1367,6 +1378,37 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
#endif // QT_NO_CSSPARSER
+void QTextHtmlParserNode::applyForegroundImage(qint64 searchKey, const QTextDocument *resourceProvider)
+{
+ QTextDocumentPrivate *priv = resourceProvider->docHandle();
+ for (int i = 0; i < priv->formats.numFormats(); ++i) {
+ QTextCharFormat format = priv->formats.charFormat(i);
+ if (format.isValid()) {
+ QBrush brush = format.foreground();
+ if (brush.style() == Qt::TexturePattern) {
+ const bool isPixmap = qHasPixmapTexture(brush);
+
+ if (isPixmap && QCoreApplication::instance()->thread() != QThread::currentThread()) {
+ qWarning("Can't apply QPixmap outside of GUI thread");
+ return;
+ }
+
+ const qint64 cacheKey = isPixmap ? brush.texture().cacheKey() : brush.textureImage().cacheKey();
+ if (cacheKey == searchKey) {
+ QBrush b;
+ if (isPixmap)
+ b.setTexture(brush.texture());
+ else
+ b.setTextureImage(brush.textureImage());
+ b.setStyle(Qt::TexturePattern);
+ charFormat.setForeground(b);
+ }
+ }
+ }
+ }
+
+}
+
void QTextHtmlParserNode::applyBackgroundImage(const QString &url, const QTextDocument *resourceProvider)
{
if (!url.isEmpty() && resourceProvider) {
@@ -1506,7 +1548,16 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
n -= 3;
node->charFormat.setProperty(QTextFormat::FontSizeAdjustment, n);
} else if (key == QLatin1String("face")) {
- node->charFormat.setFontFamily(value);
+ if (value.contains(QLatin1Char(','))) {
+ const QStringList values = value.split(QLatin1Char(','));
+ QStringList families;
+ for (const QString &family : values)
+ families << family.trimmed();
+ node->charFormat.setFontFamilies(families);
+ node->charFormat.setFontFamily(families.at(0));
+ } else {
+ node->charFormat.setFontFamily(value);
+ }
} else if (key == QLatin1String("color")) {
QColor c; c.setNamedColor(value);
if (!c.isValid())
diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h
index 6ce294d211..c174b54a61 100644
--- a/src/gui/text/qtexthtmlparser_p.h
+++ b/src/gui/text/qtexthtmlparser_p.h
@@ -251,6 +251,7 @@ struct QTextHtmlParserNode {
void setListStyle(const QVector<QCss::Value> &cssValues);
#endif
+ void applyForegroundImage(qint64 cacheKey, const QTextDocument *resourceProvider);
void applyBackgroundImage(const QString &url, const QTextDocument *resourceProvider);
bool hasOnlyWhitespace() const;
diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp
index 8a9bb3953c..b96263f5fc 100644
--- a/src/gui/text/qtextmarkdownimporter.cpp
+++ b/src/gui/text/qtextmarkdownimporter.cpp
@@ -440,7 +440,7 @@ int QTextMarkdownImporter::cbText(int textType, const char *text, unsigned size)
#endif
case MD_TEXT_HTML:
// count how many tags are opened and how many are closed
-#if QT_CONFIG(regularexpression)
+#if QT_CONFIG(regularexpression) && QT_CONFIG(texthtmlparser)
{
int startIdx = 0;
while ((startIdx = s.indexOf(openingBracket, startIdx)) >= 0) {
diff --git a/src/gui/text/qtextmarkdownwriter.cpp b/src/gui/text/qtextmarkdownwriter.cpp
index f351c8d20b..cbfb092485 100644
--- a/src/gui/text/qtextmarkdownwriter.cpp
+++ b/src/gui/text/qtextmarkdownwriter.cpp
@@ -47,6 +47,9 @@
#include "qtextcursor.h"
#include "qtextimagehandler_p.h"
#include "qloggingcategory.h"
+#if QT_CONFIG(itemmodel)
+#include "qabstractitemmodel.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -70,6 +73,7 @@ bool QTextMarkdownWriter::writeAll(const QTextDocument *document)
return true;
}
+#if QT_CONFIG(itemmodel)
void QTextMarkdownWriter::writeTable(const QAbstractItemModel *table)
{
QVector<int> tableColumnWidths(table->columnCount());
@@ -101,6 +105,7 @@ void QTextMarkdownWriter::writeTable(const QAbstractItemModel *table)
}
m_listInfo.clear();
}
+#endif
void QTextMarkdownWriter::writeFrame(const QTextFrame *frame)
{
diff --git a/src/gui/text/qtextmarkdownwriter_p.h b/src/gui/text/qtextmarkdownwriter_p.h
index 90310250ac..c3076155d0 100644
--- a/src/gui/text/qtextmarkdownwriter_p.h
+++ b/src/gui/text/qtextmarkdownwriter_p.h
@@ -56,16 +56,19 @@
#include "qtextdocument_p.h"
#include "qtextdocumentwriter.h"
-#include "QAbstractTableModel"
QT_BEGIN_NAMESPACE
+class QAbstractItemModel;
+
class Q_GUI_EXPORT QTextMarkdownWriter
{
public:
QTextMarkdownWriter(QTextStream &stream, QTextDocument::MarkdownFeatures features);
bool writeAll(const QTextDocument *document);
+#if QT_CONFIG(itemmodel)
void writeTable(const QAbstractItemModel *table);
+#endif
int writeBlock(const QTextBlock &block, bool table, bool ignoreFormat, bool ignoreEmpty);
void writeFrame(const QTextFrame *frame);