diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 1 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qdistancefield.cpp | 7 | ||||
-rw-r--r-- | src/gui/text/qdistancefield_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qfont.cpp | 30 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 7 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qplatformfontdatabase.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qrawfont_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qstatictext.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 18 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentlayout.cpp | 12 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 42 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextmarkdownimporter.cpp | 2 |
17 files changed, 98 insertions, 37 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..5555422b82 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -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; @@ -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..5350a9c5ec 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -695,7 +695,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 @@ -977,7 +978,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; } @@ -2826,7 +2827,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..2ec3f41f42 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; @@ -2468,9 +2470,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; } 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..df00fb7d84 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; }; 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..0b1a23f399 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) { 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) { |