From ee77ee5c25f58271e6f2863225d08573da86c3ee Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 20 Jun 2011 10:01:55 +0200 Subject: Make it possible to set color of QStaticText with pixel size >= 64 Adding the fallback to QPainterPath for large QStaticTexts created a regression where all text would be painted in black regardless of the color you set on it. The color in QStaticTextItem is sometimes invalid, in which case the current painter color should be used. In either case, the color is already set on the current pen when entering drawStaticTextItem() so we can just use that. Task-number: QTBUG-19950 Reviewed-by: Jiang Jiang --- src/gui/painting/qpaintengineex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 8510416..5105d9a 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1084,7 +1084,7 @@ void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem) changedHints = true; } - fill(qtVectorPathForPath(path), staticTextItem->color); + fill(qtVectorPathForPath(path), s->pen.color()); if (changedHints) { s->renderHints = oldHints; -- cgit v0.12 From cb760eaef631abd49836ae5c8dc12a61ef5eff0d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 20 Jun 2011 10:40:01 +0200 Subject: Fix empty lines in Qt HTML when displayed in external browsers (again) This redoes f541c78e1bc5b293466b40e6f10496199a4a5d73 in a way which should be more compliant with different browsers. In particular, Outlook didn't support the CSS trick in the last fix, so we need the somewhat larger patch which adds an extra line break node to the tree and then ignores it when re-importing the document. Task-number: QTBUG-3669 Reviewed-by: Simon Hausmann --- src/gui/text/qtextdocument.cpp | 4 +++- src/gui/text/qtextdocumentfragment.cpp | 9 +++++++-- src/gui/text/qtextdocumentfragment_p.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 74b1c69..b9f0b24 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2553,7 +2553,7 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) const bool emptyBlock = block.begin().atEnd(); if (emptyBlock) { - html += QLatin1String("-qt-paragraph-type:empty; height:1em;"); + html += QLatin1String("-qt-paragraph-type:empty;"); } emitMargins(QString::number(format.topMargin()), @@ -2709,6 +2709,8 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) emitBlockAttributes(block); html += QLatin1Char('>'); + if (block.begin().atEnd()) + html += "
"; QTextBlock::Iterator it = block.begin(); if (fragmentMarkers && !it.atEnd() && block == doc->begin()) diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 042b1d0..0c8860e 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -545,8 +545,13 @@ void QTextHtmlImporter::import() } if (currentNode->isBlock()) { - if (processBlockNode() == ContinueWithNextNode) + QTextHtmlImporter::ProcessNodeResult result = processBlockNode(); + if (result == ContinueWithNextNode) { continue; + } else if (result == ContinueWithNextSibling) { + currentNodeIdx += currentNode->children.size(); + continue; + } } if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) { @@ -1157,7 +1162,7 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode() if (currentNode->isEmptyParagraph) { hasBlock = false; - return ContinueWithNextNode; + return ContinueWithNextSibling; } hasBlock = true; diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h index bfbec30..227123e 100644 --- a/src/gui/text/qtextdocumentfragment_p.h +++ b/src/gui/text/qtextdocumentfragment_p.h @@ -135,7 +135,7 @@ private: Table scanTable(int tableNodeIdx); - enum ProcessNodeResult { ContinueWithNextNode, ContinueWithCurrentNode }; + enum ProcessNodeResult { ContinueWithNextNode, ContinueWithCurrentNode, ContinueWithNextSibling }; void appendBlock(const QTextBlockFormat &format, QTextCharFormat charFmt = QTextCharFormat()); bool appendNodeText(); -- cgit v0.12 From 429f0507a68f4aa686449308af770ce5cf2c913f Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 20 Jun 2011 13:47:01 +0200 Subject: Fix fontconfig usage in X11 font database We should do FcConfigSubstitute(0, pattern, FcMatchFont) on a FcPattern for query because the family list in it will contain almost all the families after FcConfigSubstitute(0, pattern, FcMatchPattern), then the test in will almost always succeed. In general, FcMatchFont substitute should only be done on the FcPattern that we got after FcFontMatch() or FcFontRenderPrepare(). Based on the suggestion of fontconfig author Behdad Esfahbod, this patch reorganized the tryPatternLoad logic so that it only does the QFontEngine creation part, FcPattern *match is retrieved outside of that function. In this way, the match pattern we got can be either from FcFontMatch() or after FcFontRenderPrepare() on one of the fonts we got from qt_fontSetForPattern(). Then we don't need to duplicate the pattern and add all criterias back with qt_addPatternProps(). It not only simplified the code a lot but also fix the way we apply FcMatchFont substitution. This substitution will either be done by FcFontMatch() or FcFontRenderPrepare, both implicitly. Task-number: QTBUG-2148, QTBUG-19947 Reviewed-by: Eskil --- src/gui/text/qfontdatabase_x11.cpp | 55 ++++++++++++++++---------------------- src/gui/text/qfontengine_x11.cpp | 23 +++++----------- 2 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 754334c..958daa2 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1566,9 +1566,8 @@ static FcPattern *getFcPattern(const QFontPrivate *fp, int script, const QFontDe qt_addPatternProps(pattern, fp->screen, script, request); - FcDefaultSubstitute(pattern); FcConfigSubstitute(0, pattern, FcMatchPattern); - FcConfigSubstitute(0, pattern, FcMatchFont); + FcDefaultSubstitute(pattern); // these should only get added to the pattern _after_ substitution // append the default fallback font for the specified script @@ -1606,35 +1605,20 @@ static void FcFontSetRemove(FcFontSet *fs, int at) memmove(fs->fonts + at, fs->fonts + at + 1, len); } -static QFontEngine *tryPatternLoad(FcPattern *p, int screen, - const QFontDef &request, int script, FcPattern **matchedPattern = 0) +static QFontEngine *tryPatternLoad(FcPattern *match, int screen, + const QFontDef &request, int script) { #ifdef FONT_MATCH_DEBUG FcChar8 *fam; - FcPatternGetString(p, FC_FAMILY, 0, &fam); + FcPatternGetString(match, FC_FAMILY, 0, &fam); FM_DEBUG("==== trying %s\n", fam); #endif FM_DEBUG("passes charset test\n"); - FcPattern *pattern = FcPatternDuplicate(p); - // add properties back in as the font selected from the - // list doesn't contain them. - qt_addPatternProps(pattern, screen, script, request); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - FcResult res; - FcPattern *match = FcFontMatch(0, pattern, &res); - - if (matchedPattern) - *matchedPattern = 0; QFontEngineX11FT *engine = 0; if (!match) // probably no fonts available. goto done; - if (matchedPattern) - *matchedPattern = FcPatternDuplicate(match); - if (script != QUnicodeTables::Common) { // skip font if it doesn't support the language we want if (specialChars[script]) { @@ -1673,11 +1657,6 @@ static QFontEngine *tryPatternLoad(FcPattern *p, int screen, } } done: - FcPatternDestroy(pattern); - if (!engine && matchedPattern && *matchedPattern) { - FcPatternDestroy(*matchedPattern); - *matchedPattern = 0; - } return engine; } @@ -1726,14 +1705,26 @@ static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &r #endif QFontEngine *fe = 0; - FcPattern *matchedPattern = 0; - fe = tryPatternLoad(pattern, fp->screen, request, script, &matchedPattern); + FcResult res; + FcPattern *match = FcFontMatch(0, pattern, &res); + fe = tryPatternLoad(match, fp->screen, request, script); if (!fe) { FcFontSet *fs = qt_fontSetForPattern(pattern, request); + if (match) { + FcPatternDestroy(match); + match = 0; + } + if (fs) { - for (int i = 0; !fe && i < fs->nfont; ++i) - fe = tryPatternLoad(fs->fonts[i], fp->screen, request, script, &matchedPattern); + for (int i = 0; !fe && i < fs->nfont; ++i) { + match = FcFontRenderPrepare(NULL, pattern, fs->fonts[i]); + fe = tryPatternLoad(match, fp->screen, request, script); + if (fe) + break; + FcPatternDestroy(match); + match = 0; + } FcFontSetDestroy(fs); } FM_DEBUG("engine for script %d is %s\n", script, fe ? fe->fontDef.family.toLatin1().data(): "(null)"); @@ -1741,11 +1732,11 @@ static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &r if (fe && script == QUnicodeTables::Common && !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) { - fe = new QFontEngineMultiFT(fe, matchedPattern, pattern, fp->screen, request); + fe = new QFontEngineMultiFT(fe, match, pattern, fp->screen, request); } else { FcPatternDestroy(pattern); - if (matchedPattern) - FcPatternDestroy(matchedPattern); + if (match) + FcPatternDestroy(match); } return fe; } diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index e3bfa5d..c4ed0ca 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -863,11 +863,8 @@ glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const // Multi FT engine // ------------------------------------------------------------------ -static QFontEngine *engineForPattern(FcPattern *pattern, const QFontDef &request, - int screen) +static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen) { - FcResult res; - FcPattern *match = FcFontMatch(0, pattern, &res); QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen); if (!engine->invalid()) return engine; @@ -879,9 +876,9 @@ static QFontEngine *engineForPattern(FcPattern *pattern, const QFontDef &request } QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req) - : QFontEngineMulti(2), request(req), pattern(p), firstEnginePattern(matchedPattern), fontSet(0), screen(s) + : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s) { - + firstEnginePattern = FcPatternDuplicate(matchedPattern); engines[0] = fe; engines.at(0)->ref.ref(); fontDef = engines[0]->fontDef; @@ -907,8 +904,6 @@ void QFontEngineMultiFT::loadEngine(int at) extern QMutex *qt_fontdatabase_mutex(); QMutexLocker locker(qt_fontdatabase_mutex()); - extern void qt_addPatternProps(FcPattern *pattern, int screen, int script, - const QFontDef &request); extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &); extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request); @@ -940,22 +935,18 @@ void QFontEngineMultiFT::loadEngine(int at) Q_ASSERT(at < engines.size()); Q_ASSERT(engines.at(at) == 0); - FcPattern *pattern = FcPatternDuplicate(fontSet->fonts[at + firstFontIndex - 1]); - qt_addPatternProps(pattern, screen, QUnicodeTables::Common, request); - - QFontDef fontDef = qt_FcPatternToQFontDef(pattern, this->request); + FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]); + QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request); // note: we use -1 for the script to make sure that we keep real // FT engines separate from Multi engines in the font cache QFontCache::Key key(fontDef, -1, screen); QFontEngine *fontEngine = QFontCache::instance()->findEngine(key); if (!fontEngine) { - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - fontEngine = engineForPattern(pattern, request, screen); + fontEngine = engineForPattern(match, request, screen); QFontCache::instance()->insertEngine(key, fontEngine); } - FcPatternDestroy(pattern); + FcPatternDestroy(match); fontEngine->ref.ref(); engines[at] = fontEngine; } -- cgit v0.12 From 94db89e69c3b08db111f6434dcc7a7d39f756574 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 20 Jun 2011 14:52:00 +0200 Subject: No need to destroy match pattern again It is already freed in QFontEngineX11FT constructor. Reviewed-by: Eskil --- src/gui/text/qfontengine_x11.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index c4ed0ca..74c0130 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -946,7 +946,6 @@ void QFontEngineMultiFT::loadEngine(int at) fontEngine = engineForPattern(match, request, screen); QFontCache::instance()->insertEngine(key, fontEngine); } - FcPatternDestroy(match); fontEngine->ref.ref(); engines[at] = fontEngine; } -- cgit v0.12 From 39dffd14b9544955e294899ca7125a0b913607c6 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 21 Jun 2011 09:25:19 +0200 Subject: Proper fix for previous deallocation problem The match FcPattern should be managed by QFontDatabase instead of QFontEngineX11FT since the latter only used it once. Reviewed-by: Samuel --- src/gui/text/qfontengine_x11.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 74c0130..490866c 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -946,6 +946,7 @@ void QFontEngineMultiFT::loadEngine(int at) fontEngine = engineForPattern(match, request, screen); QFontCache::instance()->insertEngine(key, fontEngine); } + FcPatternDestroy(match); fontEngine->ref.ref(); engines[at] = fontEngine; } @@ -1113,17 +1114,14 @@ QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int s } #endif - if (!init(face_id, antialias, defaultFormat)) { - FcPatternDestroy(pattern); + if (!init(face_id, antialias, defaultFormat)) return; - } if (!freetype->charset) { FcCharSet *cs; FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs); freetype->charset = FcCharSetCopy(cs); } - FcPatternDestroy(pattern); } QFontEngineX11FT::~QFontEngineX11FT() -- cgit v0.12 From 2701802511d9c09a11212cc37838154245b0c0ca Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 21 Jun 2011 11:23:20 +0200 Subject: Update autotest case after toHtml change cb760eaef631abd49836ae5c8dc12a61ef5eff0d changed the way we generate HTML for empty blocks. tst_QTextDocument::toHtml has to be updated accordingly. Reviewed-by: Samuel --- tests/auto/qtextdocument/tst_qtextdocument.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 68252ef..c98a703 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -1584,7 +1584,7 @@ void tst_QTextDocument::toHtml() expectedOutput.replace("OPENDEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"); expectedOutput.replace("DEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\""); - expectedOutput.replace("EMPTYBLOCK", "

\n"); + expectedOutput.replace("EMPTYBLOCK", "


\n"); if (expectedOutput.endsWith(QLatin1Char('\n'))) expectedOutput.chop(1); expectedOutput.append(htmlTail); -- cgit v0.12