summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-04-15 20:47:37 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-04-15 21:43:17 -0400
commit087a79db1272858f107656c5ca3c6efb45680986 (patch)
tree90685fbbf5b9f80f32bf474cf0fb8c1eae42e321
parent74d7911abf77643544c58a0d3e5fb956add76c44 (diff)
fdo#75665: Truncate string when clipped on screen.
This improves performance of text layouting by HarfBuzz for very long strings. HarfBuzz's layout algorithm appears to be more expensive than ICU's. Change-Id: Ic9738b7b8f0f1a29c51c83b147763118939b90ef
-rw-r--r--sc/source/ui/inc/output.hxx2
-rw-r--r--sc/source/ui/view/output2.cxx34
2 files changed, 31 insertions, 5 deletions
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 0aee29fdc55f..6e542e48f080 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -66,6 +66,8 @@ private:
Rectangle maAlignRect;
Rectangle maClipRect;
long mnColWidth;
+ long mnLeftClipLength; /// length of the string getting cut off on the left.
+ long mnRightClipLength; /// length of the string getting cut off on the right.
bool mbLeftClip;
bool mbRightClip;
};
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 321cf04208d8..90d562e33996 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1238,7 +1238,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY
--nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines)
rParam.mnColWidth = nMergeSizeX; // store the actual column width.
-
+ rParam.mnLeftClipLength = rParam.mnRightClipLength = 0;
// construct the rectangles using logical left/right values (justify is called at the end)
@@ -1331,6 +1331,8 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY
rParam.mbLeftClip = ( nLeftMissing > 0 );
rParam.mbRightClip = ( nRightMissing > 0 );
+ rParam.mnLeftClipLength = nLeftMissing;
+ rParam.mnRightClipLength = nRightMissing;
}
else
{
@@ -2024,13 +2026,35 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
OUString aString = aVars.GetString();
if (!aString.isEmpty())
{
+ // If the string is clipped, make it shorter for
+ // better performance since drawing by HarfBuzz is
+ // quite expensive especiall for long string.
+
+ OUString aShort = aString;
+
+ double fVisibleRatio = 1.0;
+ double fTextWidth = aVars.GetTextSize().Width();
+ if (eOutHorJust == SVX_HOR_JUSTIFY_LEFT && aAreaParam.mnRightClipLength > 0)
+ fVisibleRatio = (fTextWidth - aAreaParam.mnRightClipLength) / fTextWidth;
+ else if (eOutHorJust == SVX_HOR_JUSTIFY_RIGHT && aAreaParam.mnLeftClipLength > 0)
+ fVisibleRatio = (fTextWidth - aAreaParam.mnLeftClipLength) / fTextWidth;
+
+ if (fVisibleRatio < 1.0)
+ {
+ // Heuristically determine the length of the
+ // visible section of the string. Length + 1
+ // to avoid becoming too short.
+ sal_Int32 nShortLen = fVisibleRatio * aString.getLength() + 1;
+ aShort = aShort.copy(0, nShortLen);
+ }
+
if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
{
- size_t nLen = aString.getLength();
+ size_t nLen = aShort.getLength();
if (aDX.size() < nLen)
aDX.resize(nLen, 0);
- pFmtDevice->GetTextArray(aString, &aDX[0]);
+ pFmtDevice->GetTextArray(aShort, &aDX[0]);
if ( !mpRefDevice->GetConnectMetaFile() ||
mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
@@ -2040,10 +2064,10 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
aDX[i] = static_cast<sal_Int32>(aDX[i] / fMul + 0.5);
}
- mpDev->DrawTextArray(aDrawTextPos, aString, &aDX[0]);
+ mpDev->DrawTextArray(aDrawTextPos, aShort, &aDX[0]);
}
else
- mpDev->DrawText( aDrawTextPos, aString );
+ mpDev->DrawText(aDrawTextPos, aShort);
}
if ( bHClip || bVClip )