diff --git a/src/common/textmeasurecmn.cpp b/src/common/textmeasurecmn.cpp index 8d828d4b71..16448d2664 100644 --- a/src/common/textmeasurecmn.cpp +++ b/src/common/textmeasurecmn.cpp @@ -105,17 +105,27 @@ void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text, wxCoord *height, wxCoord *heightOneLine) { + // It's noticeably faster to handle the case of a string which isn't + // actually multiline specially here, to skip iteration above in this case. + if ( text.find('\n') == wxString::npos ) + { + GetTextExtent(text, width, height); + if ( heightOneLine && height ) + *heightOneLine = *height; + return; + } + MeasuringGuard guard(*this); wxCoord widthTextMax = 0, widthLine, heightTextTotal = 0, heightLineDefault = 0, heightLine = 0; - wxString curLine; + wxString::const_iterator lineStart = text.begin(); for ( wxString::const_iterator pc = text.begin(); ; ++pc ) { if ( pc == text.end() || *pc == wxS('\n') ) { - if ( curLine.empty() ) + if ( pc == lineStart ) { // we can't use GetTextExtent - it will return 0 for both width // and height and an empty line should count in height @@ -137,7 +147,7 @@ void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text, } else { - CallGetTextExtent(curLine, &widthLine, &heightLine); + CallGetTextExtent(wxString(lineStart, pc), &widthLine, &heightLine); if ( widthLine > widthTextMax ) widthTextMax = widthLine; heightTextTotal += heightLine; @@ -149,13 +159,10 @@ void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text, } else // '\n' { - curLine.clear(); + lineStart = pc; + ++lineStart; } } - else - { - curLine += *pc; - } } if ( width ) diff --git a/tests/benchmarks/graphics.cpp b/tests/benchmarks/graphics.cpp index e2714de5de..bbbec0cd5a 100644 --- a/tests/benchmarks/graphics.cpp +++ b/tests/benchmarks/graphics.cpp @@ -66,6 +66,7 @@ struct GraphicsBenchmarkOptions testCircles = testEllipses = testTextExtent = + testMultiLineTextExtent = testPartialTextExtents = false; usePaint = @@ -95,6 +96,7 @@ struct GraphicsBenchmarkOptions testCircles, testEllipses, testTextExtent, + testMultiLineTextExtent, testPartialTextExtents; bool usePaint, @@ -634,7 +636,10 @@ private: wxStopWatch sw; for ( long n = 0; n < opts.numIters; n++ ) { - size += dc.GetTextExtent(str); + if ( opts.testMultiLineTextExtent ) + size += dc.GetMultiLineTextExtent(str); + else + size += dc.GetTextExtent(str); } const long t = sw.Time(); @@ -847,6 +852,7 @@ public: { wxCMD_LINE_SWITCH, "", "circles" }, { wxCMD_LINE_SWITCH, "", "ellipses" }, { wxCMD_LINE_SWITCH, "", "textextent" }, + { wxCMD_LINE_SWITCH, "", "multilinetextextent" }, { wxCMD_LINE_SWITCH, "", "partialtextextents" }, { wxCMD_LINE_SWITCH, "", "paint" }, { wxCMD_LINE_SWITCH, "", "client" }, @@ -922,6 +928,7 @@ public: opts.testCircles = parser.Found("circles"); opts.testEllipses = parser.Found("ellipses"); opts.testTextExtent = parser.Found("textextent"); + opts.testMultiLineTextExtent = parser.Found("multilinetextextent"); opts.testPartialTextExtents = parser.Found("partialtextextents"); if ( !(opts.testBitmaps || opts.testImages || opts.testLines || opts.testRawBitmaps || opts.testRectangles