summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-04-15 14:37:47 -0400
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-04-17 00:07:46 +0000
commit4321ca5a3ca78e4a6e6c3654dbab825036bb60e3 (patch)
treec99df5bf38fbc377874e2fc35078dfbc14eff46c
parentf7e32ba07910956bd09d79e37eb8ce6eb8a0ac30 (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. (cherry picked from commit 087a79db1272858f107656c5ca3c6efb45680986) (cherry picked from commit 6fa4d31d6a7e363285f22d4c0012521d10073652) (cherry picked from commit 8e50a6c7b1cb9481cce42c71ff07e921fb4292d0) (cherry picked from commit 21fc47e115530780ad45ae64e8076dc5e9fedb5e) Conflicts: sc/inc/scopetools.hxx sc/source/core/tool/scopetools.cxx sc/source/ui/view/output2.cxx Change-Id: Ic9738b7b8f0f1a29c51c83b147763118939b90ef Reviewed-on: https://gerrit.libreoffice.org/9057 Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sc/inc/scopetools.hxx9
-rw-r--r--sc/source/core/tool/scopetools.cxx11
-rw-r--r--sc/source/ui/inc/output.hxx2
-rw-r--r--sc/source/ui/view/output2.cxx76
4 files changed, 80 insertions, 18 deletions
diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
index 3544b79f2547..802aea127a10 100644
--- a/sc/inc/scopetools.hxx
+++ b/sc/inc/scopetools.hxx
@@ -35,6 +35,15 @@ public:
~ExpandRefsSwitch();
};
+class SC_DLLPUBLIC IdleSwitch
+{
+ ScDocument& mrDoc;
+ bool mbOldValue;
+public:
+ IdleSwitch(ScDocument& rDoc, bool bEnableIdle);
+ ~IdleSwitch();
+};
+
}
#endif
diff --git a/sc/source/core/tool/scopetools.cxx b/sc/source/core/tool/scopetools.cxx
index af65cff29e46..6f423d00e1c1 100644
--- a/sc/source/core/tool/scopetools.cxx
+++ b/sc/source/core/tool/scopetools.cxx
@@ -34,6 +34,17 @@ ExpandRefsSwitch::~ExpandRefsSwitch()
mrDoc.SetExpandRefs(mbOldValue);
}
+IdleSwitch::IdleSwitch(ScDocument& rDoc, bool bEnableIdle) :
+ mrDoc(rDoc), mbOldValue(rDoc.IsIdleEnabled())
+{
+ mrDoc.EnableIdle(bEnableIdle);
+}
+
+IdleSwitch::~IdleSwitch()
+{
+ mrDoc.EnableIdle(mbOldValue);
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 03952a8f7911..a34dab63c69b 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -70,6 +70,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 544e737d015d..75739d4c4c1f 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -60,6 +60,7 @@
#include "markdata.hxx"
#include "stlsheet.hxx"
#include "spellcheckcontext.hxx"
+#include <scopetools.hxx>
#include <com/sun/star/i18n/DirectionProperty.hpp>
#include <comphelper/string.hxx>
@@ -1245,8 +1246,8 @@ 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)
//
@@ -1338,6 +1339,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
{
@@ -1451,9 +1454,7 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, mpDev->GetExtOutDevData() );
- bool bWasIdleEnabled = mpDoc->IsIdleEnabled();
- mpDoc->EnableIdle(false);
-
+ sc::IdleSwitch aIdleSwitch(*mpDoc, false);
ScDrawStringsVars aVars( this, bPixelToLogic );
sal_Bool bProgress = false;
@@ -1485,6 +1486,7 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
// before processing the cell value.
::boost::ptr_vector<ScPatternAttr> aAltPatterns;
+ std::vector<sal_Int32> aDX;
long nPosY = nScrY;
for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
{
@@ -2030,25 +2032,64 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
// aufgezeichnet werden (fuer nicht-proportionales Resize):
OUString aString = aVars.GetString();
- if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
+ if (!aString.isEmpty())
{
- sal_Int32* pDX = new sal_Int32[aString.getLength()];
- pFmtDevice->GetTextArray( aString, pDX );
+ // 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;
- if ( !mpRefDevice->GetConnectMetaFile() ||
- mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ double fVisibleRatio = 1.0;
+ double fTextWidth = aVars.GetTextSize().Width();
+ sal_Int32 nTextLen = aString.getLength();
+ if (eOutHorJust == SVX_HOR_JUSTIFY_LEFT && aAreaParam.mnRightClipLength > 0)
{
- double fMul = GetStretch();
- sal_Int32 nLen = aString.getLength();
- for( sal_Int32 i = 0; i<nLen; i++ )
- pDX[i] = (long)(pDX[i] / fMul + 0.5);
+ fVisibleRatio = (fTextWidth - aAreaParam.mnRightClipLength) / fTextWidth;
+ if (0.0 < fVisibleRatio && fVisibleRatio < 1.0)
+ {
+ // Only show the left-end segment.
+ sal_Int32 nShortLen = fVisibleRatio*nTextLen + 1;
+ aShort = aShort.copy(0, nShortLen);
+ }
+ }
+ else if (eOutHorJust == SVX_HOR_JUSTIFY_RIGHT && aAreaParam.mnLeftClipLength > 0)
+ {
+ fVisibleRatio = (fTextWidth - aAreaParam.mnLeftClipLength) / fTextWidth;
+ if (0.0 < fVisibleRatio && fVisibleRatio < 1.0)
+ {
+ // Only show the right-end segment.
+ sal_Int32 nShortLen = fVisibleRatio*nTextLen + 1;
+ aShort = aShort.copy(nTextLen-nShortLen);
+
+ // Adjust the text position after shortening of the string.
+ double fShortWidth = pFmtDevice->GetTextWidth(aShort);
+ double fOffset = fTextWidth - fShortWidth;
+ aDrawTextPos.Move(fOffset, 0);
+ }
}
- mpDev->DrawTextArray( aDrawTextPos, aString, pDX );
- delete[] pDX;
+ if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
+ {
+ size_t nLen = aShort.getLength();
+ if (aDX.size() < nLen)
+ aDX.resize(nLen, 0);
+
+ pFmtDevice->GetTextArray(aShort, &aDX[0]);
+
+ if ( !mpRefDevice->GetConnectMetaFile() ||
+ mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = GetStretch();
+ for (size_t i = 0; i < nLen; ++i)
+ aDX[i] = static_cast<sal_Int32>(aDX[i] / fMul + 0.5);
+ }
+
+ mpDev->DrawTextArray(aDrawTextPos, aShort, &aDX[0]);
+ }
+ else
+ mpDev->DrawText(aDrawTextPos, aShort);
}
- else
- mpDev->DrawText( aDrawTextPos, aString );
if ( bHClip || bVClip )
{
@@ -2074,7 +2115,6 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
}
if ( bProgress )
ScProgress::DeleteInterpretProgress();
- mpDoc->EnableIdle(bWasIdleEnabled);
}
// -------------------------------------------------------------------------------