Kaydet (Commit) 087a79db authored tarafından Kohei Yoshida's avatar Kohei Yoshida

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
üst 74d7911a
...@@ -66,6 +66,8 @@ private: ...@@ -66,6 +66,8 @@ private:
Rectangle maAlignRect; Rectangle maAlignRect;
Rectangle maClipRect; Rectangle maClipRect;
long mnColWidth; 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 mbLeftClip;
bool mbRightClip; bool mbRightClip;
}; };
......
...@@ -1238,7 +1238,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY ...@@ -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) --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines)
rParam.mnColWidth = nMergeSizeX; // store the actual column width. 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) // 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 ...@@ -1331,6 +1331,8 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY
rParam.mbLeftClip = ( nLeftMissing > 0 ); rParam.mbLeftClip = ( nLeftMissing > 0 );
rParam.mbRightClip = ( nRightMissing > 0 ); rParam.mbRightClip = ( nRightMissing > 0 );
rParam.mnLeftClipLength = nLeftMissing;
rParam.mnRightClipLength = nRightMissing;
} }
else else
{ {
...@@ -2024,13 +2026,35 @@ void ScOutputData::DrawStrings( bool bPixelToLogic ) ...@@ -2024,13 +2026,35 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
OUString aString = aVars.GetString(); OUString aString = aVars.GetString();
if (!aString.isEmpty()) 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) if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
{ {
size_t nLen = aString.getLength(); size_t nLen = aShort.getLength();
if (aDX.size() < nLen) if (aDX.size() < nLen)
aDX.resize(nLen, 0); aDX.resize(nLen, 0);
pFmtDevice->GetTextArray(aString, &aDX[0]); pFmtDevice->GetTextArray(aShort, &aDX[0]);
if ( !mpRefDevice->GetConnectMetaFile() || if ( !mpRefDevice->GetConnectMetaFile() ||
mpRefDevice->GetOutDevType() == OUTDEV_PRINTER ) mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
...@@ -2040,10 +2064,10 @@ void ScOutputData::DrawStrings( bool bPixelToLogic ) ...@@ -2040,10 +2064,10 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
aDX[i] = static_cast<sal_Int32>(aDX[i] / fMul + 0.5); aDX[i] = static_cast<sal_Int32>(aDX[i] / fMul + 0.5);
} }
mpDev->DrawTextArray(aDrawTextPos, aString, &aDX[0]); mpDev->DrawTextArray(aDrawTextPos, aShort, &aDX[0]);
} }
else else
mpDev->DrawText( aDrawTextPos, aString ); mpDev->DrawText(aDrawTextPos, aShort);
} }
if ( bHClip || bVClip ) if ( bHClip || bVClip )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment