sc/inc/scopetools.hxx              |    9 ++++
 sc/source/core/tool/scopetools.cxx |   11 +++++
 sc/source/ui/inc/output.hxx        |    2 
 sc/source/ui/view/output2.cxx      |   76 ++++++++++++++++++++++++++++---------
 4 files changed, 80 insertions(+), 18 deletions(-)

New commits:
commit 4321ca5a3ca78e4a6e6c3654dbab825036bb60e3
Author: Kohei Yoshida <kohei.yosh...@collabora.com>
Date:   Tue Apr 15 14:37:47 2014 -0400

    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.mohrh...@googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com>

diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
index 3544b79..802aea1 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 af65cff..6f423d0 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 03952a8..a34dab6 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 544e737..75739d4 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);
 }
 
 //  
-------------------------------------------------------------------------------
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to