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 From a5c3064439a9f1483565e5d9dfbf0342cd9236f0 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 22 Jun 2011 14:23:47 +0200 Subject: Skip boundry neutral characters in bidi itemization According to UAX #9, bidiItemize should act as if those characters don't exist. If we don't, dir and status.eor here may become QChar::DirBN, thus interfere the result of bidiItemize. Task-number: QTBUG-19949 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 26 ++++++++++++++++++++++---- tests/auto/qcomplextext/bidireorderstring.h | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) 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 } }; -- cgit v0.12 From 45d2d36c9dbcbce403c78838ea52acd1ab111b68 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Dec 2010 19:52:48 +0100 Subject: Add an SSE4.2 even simpler version of toLatin1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new PCMPESTRM instruction (Parallel CoMPare Explicit-length STRings with result in a Mask) which is added in SSE4.2 for facilitating string operations. The "compare ranges" mode allows us to search for characters outside the Latin 1 range and then use the SSE4.1 PBLENDVB instruction to replace those with question marks. Unlike previous SSE compare instructions, the PCMPxSTRx family allows us to operate on unsigned 16-bit values. This saves us another parallel add. Reviewed-By: Samuel Rødal --- src/corelib/tools/qstring.cpp | 23 +++++++++++++++++++++++ tests/auto/qstring/tst_qstring.cpp | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 0edf291..0828ccb 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3561,6 +3561,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); @@ -3584,6 +3606,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/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() -- cgit v0.12 From 59bd3bcd961fb3198dc9ba24996f7f9af67aeda3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jun 2011 21:14:01 +0200 Subject: Add a function that returns the D-Bus local machine ID Reviewed-by: Lars Knoll --- src/dbus/qdbus_symbols_p.h | 2 ++ src/dbus/qdbusconnection.cpp | 21 +++++++++++++++++++++ src/dbus/qdbusconnection.h | 2 ++ 3 files changed, 25 insertions(+) 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 6628ca3..94989f5 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -1123,6 +1123,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(); -- cgit v0.12 From c74b93df047157a6ff8ca3ffa2dd2f624760824f Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Fri, 24 Jun 2011 14:00:17 +0100 Subject: runonphone: Fix usb device enumeration on Mac OS X The change in 763f3acd879648648465475aef773fe0876934a9, when merged in a315c693d0f3dd64711b8459d86b89ddc48e8c1a, broke the usb device enumeration on OS X. This commit makes it work again, but now we look for two /dev entries per device (although only one of them exists). If many usb devices are connected, this increases the risk for false matches - if that ever happens, the iteration/checking that was removed in 763f3acd879648648465475aef773fe0876934a9 could be readded within the #ifdef Q_OS_MAC, making it add only one regexp per device again. Merge-request: 2633 Reviewed-by: Shane Kearns --- tools/runonphone/serenum_unix.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index dc9e1d6..d0e7665 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -148,7 +148,8 @@ QList enumerateSerialPorts(int loglevel) foreach (int i, usableInterfaces) { #ifdef Q_OS_MAC eligibleInterfaces << QString("^cu\\.usbmodem.*%1$") - .arg(QString("%1").arg(descriptor.bInterfaceNumber, 1, 16).toUpper()); + .arg(QString("%1").arg(i, 1, 16).toUpper()); + eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct); #else // ### manufacturer and product strings are only readable as root :( if (!manufacturerString.isEmpty() && !productString.isEmpty()) { @@ -161,7 +162,11 @@ QList enumerateSerialPorts(int loglevel) } #endif } +#ifndef Q_OS_MAC + // On mac, we need a 1-1 mapping between eligibleInterfaces and eligibleInterfacesInfo + // in order to find the friendly name for an interface eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct); +#endif } } } -- cgit v0.12 From 75c04d43cc8264f142d26f9524b325dbc362cae5 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Fri, 24 Jun 2011 14:00:19 +0100 Subject: runonphone: Include the manufacturer name in the friendly name on OS X This helps automatic detection of devices such as N8-00, that don't include Nokia in the product name (while devices from earlier generations did include it, such as "Nokia 5800 XpressMusic"). Merge-request: 2633 Reviewed-by: Shane Kearns --- tools/runonphone/serenum_unix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index d0e7665..9a33dab 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -190,7 +190,8 @@ QList enumerateSerialPorts(int loglevel) if (loglevel > 1) qDebug() << " found device file:" << info.fileName() << endl; #ifdef Q_OS_MAC - friendlyName = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)].product; + InterfaceInfo info = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)]; + friendlyName = info.manufacturer + " " + info.product; #endif usable = true; break; -- cgit v0.12 From 37a21edbfb01f902bbfc033727066ed1ee1354e7 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Fri, 24 Jun 2011 14:00:29 +0100 Subject: runonphone: Change the upload option to allow uploading any file This allows uploading of any file to any directory on the phone. Merge-request: 1271 Reviewed-by: Shane Kearns --- tools/runonphone/main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index e400062..d749106 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -62,7 +62,7 @@ void printUsage(QTextStream& outstream, QString exeName) << "-t, --timeout terminate test if timeout occurs" << endl << "-v, --verbose show debugging output" << endl << "-q, --quiet hide progress messages" << endl - << "-u, --upload upload executable file to phone" << endl + << "-u, --upload upload file to phone" << endl << "-d, --download copy file from phone to PC after running test" << endl << "--nocrashlog Don't capture call stack if test crashes" << endl << "--crashlogpath Path to save crash logs (default=working dir)" << endl @@ -86,6 +86,7 @@ int main(int argc, char *argv[]) QTextStream outstream(stdout); QTextStream errstream(stderr); QString uploadLocalFile; + QString uploadRemoteFile; QString downloadRemoteFile; QString downloadLocalFile; int loglevel=1; @@ -121,10 +122,8 @@ int main(int argc, char *argv[]) errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl; return 1; } - if (!(QFileInfo(uploadLocalFile).suffix() == "exe")) { - errstream << "File (" << uploadLocalFile << ") must be an executable" << endl; - return 1; - } + CHECK_PARAMETER_EXISTS + uploadRemoteFile = it.next(); } else if (arg == "--download" || arg == "-d") { CHECK_PARAMETER_EXISTS @@ -161,7 +160,8 @@ int main(int argc, char *argv[]) } } - if (exeFile.isEmpty() && sisFile.isEmpty() && uploadLocalFile.isEmpty() && + if (exeFile.isEmpty() && sisFile.isEmpty() && + (uploadLocalFile.isEmpty() || uploadRemoteFile.isEmpty()) && (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) { printUsage(outstream, args[0]); return 1; @@ -211,7 +211,7 @@ int main(int argc, char *argv[]) } else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { launcher->addStartupActions(trk::Launcher::ActionCopy); - launcher->setCopyFileName(uploadLocalFile, QString("c:\\sys\\bin\\") + uploadInfo.fileName()); + launcher->setCopyFileName(uploadLocalFile, uploadRemoteFile); } if (!exeFile.isEmpty()) { launcher->addStartupActions(trk::Launcher::ActionRun); -- cgit v0.12