[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Apr 16 17:08:13 PDT 2014


 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.yoshida at 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.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at 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);
 }
 
 //  -------------------------------------------------------------------------------


More information about the Libreoffice-commits mailing list