diff options
-rw-r--r-- | src/corelib/tools/qstring.cpp | 23 | ||||
-rw-r--r-- | src/dbus/qdbus_symbols_p.h | 2 | ||||
-rw-r--r-- | src/dbus/qdbusconnection.cpp | 21 | ||||
-rw-r--r-- | src/dbus/qdbusconnection.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_x11.cpp | 55 | ||||
-rw-r--r-- | src/gui/text/qfontengine_x11.cpp | 28 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentfragment.cpp | 9 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentfragment_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 26 | ||||
-rw-r--r-- | tests/auto/qcomplextext/bidireorderstring.h | 1 | ||||
-rw-r--r-- | tests/auto/qstring/tst_qstring.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qtextdocument/tst_qtextdocument.cpp | 2 |
14 files changed, 119 insertions, 62 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index f8f4bdc..ee45cfd 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3580,6 +3580,28 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) { const __m128i questionMark = _mm_set1_epi16('?'); +# ifdef __SSE4_2__ + // compare the unsigned shorts for the range 0x0100-0xFFFF + // note on the use of _mm_cmpestrm: + // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx) + // says for range search the following: + // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3 + // + // However, all examples on the Internet, including from Intel + // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/) + // put the range to be searched first + // + // Disassembly and instruction-level debugging with GCC and ICC show + // that they are doing the right thing. Inverting the arguments in the + // instruction does cause a bunch of test failures. + + const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK; + const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100); + const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode); + + // replace the non-Latin 1 characters in the chunk with question marks + chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask); +# else // SSE has no compare instruction for unsigned comparison. // The variables must be shiffted + 0x8000 to be compared const __m128i signedBitOffset = _mm_set1_epi16(0x8000); @@ -3603,6 +3625,7 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) // merge offLimitQuestionMark and correctBytes to have the result chunk = _mm_or_si128(correctBytes, offLimitQuestionMark); # endif +# endif return chunk; } #endif diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index 8b46e6a..a59c08a 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -301,6 +301,8 @@ DEFINEFUNC(void , dbus_get_version , (int *major_version_p, int *minor_version_p, int *micro_version_p), (major_version_p, minor_version_p, micro_version_p), ) +DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return) + /* dbus-pending-call.h */ DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending, diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 58c1caa..0b4133c 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -1124,6 +1124,27 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection) } /*! + \since 4.8 + Returns the local machine ID as known to the D-Bus system. Each + node or host that runs D-Bus has a unique identifier that can be + used to distinguish it from other hosts if they are sharing + resources like the filesystem. + + Note that the local machine ID is not guaranteed to be persistent + across boots of the system, so this identifier should not be + stored in persistent storage (like the filesystem). It is + guaranteed to remain constant only during the lifetime of this + boot session. +*/ +QByteArray QDBusConnection::localMachineId() +{ + char *dbus_machine_id = q_dbus_get_local_machine_id(); + QByteArray result = dbus_machine_id; + q_dbus_free(dbus_machine_id); + return result; +} + +/*! \namespace QDBus \inmodule QtDBus diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 19418d6..4bdd055 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -176,6 +176,8 @@ public: static void disconnectFromBus(const QString &name); static void disconnectFromPeer(const QString &name); + static QByteArray localMachineId(); + static QDBusConnection sessionBus(); static QDBusConnection systemBus(); 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; 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..490866c 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; } @@ -1123,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() diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 41b6fe2..0abafb8 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 += "<br />"; 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(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index e8e6c98..8ddf3eb 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -319,6 +319,26 @@ static void appendItems(QScriptAnalysis *analysis, int &start, int &stop, const start = stop; } +static QChar::Direction skipBoundryNeutrals(QScriptAnalysis *analysis, + const ushort *unicode, int length, + int &sor, int &eor, QBidiControl &control) +{ + QChar::Direction dir; + int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level; + while (sor < length) { + dir = QChar::direction(unicode[sor]); + // Keep skipping DirBN as if it doesn't exist + if (dir != QChar::DirBN) + break; + analysis[sor++].bidiLevel = level; + } + + eor = sor; + if (eor == length) + dir = control.basicDirection(); + + return dir; +} // creates the next QScript items. static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiControl &control) @@ -430,8 +450,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon case QChar::DirAN: if (eor >= 0) { appendItems(analysis, sor, eor, control, dir); - dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection(); - status.eor = dir; + status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control); } else { eor = current; status.eor = dir; } @@ -455,8 +474,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon } eor = current - 1; appendItems(analysis, sor, eor, control, dir); - dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection(); - status.eor = dir; + status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control); } else { if(status.eor != QChar::DirL) { appendItems(analysis, sor, eor, control, dir); diff --git a/tests/auto/qcomplextext/bidireorderstring.h b/tests/auto/qcomplextext/bidireorderstring.h index e51011e..e0bbf6e 100644 --- a/tests/auto/qcomplextext/bidireorderstring.h +++ b/tests/auto/qcomplextext/bidireorderstring.h @@ -145,6 +145,7 @@ const LV logical_visual[] = { { "embed10", "\342\200\253x \327\251\327\234\327\225\327\235 y\342\200\254", "\342\200\254y \327\235\327\225\327\234\327\251 x\342\200\253", QChar::DirL }, { "embed11", "\342\200\252x \327\251\327\234\327\225\327\235 y\342\200\254", "\342\200\252x \327\235\327\225\327\234\327\251 y\342\200\254", QChar::DirR }, { "embed12", "\342\200\253x \327\251\327\234\327\225\327\235 y\342\200\254", "\342\200\254y \327\235\327\225\327\234\327\251 x\342\200\253", QChar::DirR }, + { "zwsp", "+0\342\200\213f-1", "+0\342\200\213f-1", QChar::DirL }, { 0, 0, 0, QChar::DirON } }; diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index c19b168..b26121c 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -3475,6 +3475,10 @@ void tst_QString::toLatin1Roundtrip_data() static const ushort unicode6[] = { 0x180, 0x1ff, 0x8001, 0x8080, 0xfffc }; QTest::newRow("non-latin1b") << QByteArray("?????") << QString::fromUtf16(unicode6, 5) << questionmarks; + + static const ushort unicode7[] = { 'H', 'e', 'l', 'l', 'o', 0x100, 0x17f, 0x180, 0x8080, 0xfffc }; + static const ushort unicode7q[] = { 'H', 'e', 'l', 'l', 'o', '?', '?', '?', '?', '?' }; + QTest::newRow("mixed") << QByteArray("Hello?????") << QString::fromUtf16(unicode7, 10) << QString::fromUtf16(unicode7q, 10); } void tst_QString::toLatin1Roundtrip() 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", "<p style=\"-qt-paragraph-type:empty; height:1em; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"); + expectedOutput.replace("EMPTYBLOCK", "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"); if (expectedOutput.endsWith(QLatin1Char('\n'))) expectedOutput.chop(1); expectedOutput.append(htmlTail); |