[Libreoffice-commits] core.git: 2 commits - sw/source vcl/source

Caolán McNamara caolanm at redhat.com
Mon Aug 26 13:11:11 PDT 2013


 sw/source/filter/ww8/hash_wrap.hxx   |    6 -
 sw/source/filter/ww8/sortedarray.hxx |    6 -
 vcl/source/control/tabctrl.cxx       |  140 ++++++++++++++++++++++++++++-------
 3 files changed, 119 insertions(+), 33 deletions(-)

New commits:
commit 55cdf3c5f44afe47cbe9eb32cc4f6fdcb6106d8d
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Aug 26 21:10:27 2013 +0100

    most debug-level OUString::valueOf
    
    Change-Id: I3e3cebe225e27a33be423c8b5fa2261b4a48e88c

diff --git a/sw/source/filter/ww8/hash_wrap.hxx b/sw/source/filter/ww8/hash_wrap.hxx
index 189e4b1..55231b9 100644
--- a/sw/source/filter/ww8/hash_wrap.hxx
+++ b/sw/source/filter/ww8/hash_wrap.hxx
@@ -88,11 +88,11 @@ namespace ww
                         reinterpret_cast<const sal_uInt8 *>(&(*pIter));
                     for (size_t i=0; i < nSize; ++i)
                     {
-                        sError += OUString::valueOf(
+                        sError += OUString::number(
                             static_cast<sal_Int32>(pHack[i]), 16);
-                        sError += OUString::valueOf(sal_Unicode(' '));
+                        sError += OUString(' ');
                     }
-                    sError += OUString::valueOf(sal_Unicode('\n'));
+                    sError += OUString('\n');
                     while (*pIter == *(pIter+1) && pIter < pBeforeEnd)
                         ++pIter;
                 }
diff --git a/sw/source/filter/ww8/sortedarray.hxx b/sw/source/filter/ww8/sortedarray.hxx
index 9a596ed..5f975a7 100644
--- a/sw/source/filter/ww8/sortedarray.hxx
+++ b/sw/source/filter/ww8/sortedarray.hxx
@@ -85,11 +85,11 @@ namespace ww
                         reinterpret_cast<const sal_uInt8 *>(&(*pIter));
                     for (size_t i=0; i < nSize; ++i)
                     {
-                        sError += OUString::valueOf(
+                        sError += OUString::number(
                             static_cast<sal_Int32>(pHack[i]), 16);
-                        sError += OUString::valueOf(sal_Unicode(' '));
+                        sError += OUString(' ');
                     }
-                    sError += OUString::valueOf(sal_Unicode('\n'));
+                    sError += OUString('\n');
                     while (*pIter == *(pIter+1) && pIter < pBeforeEnd)
                         ++pIter;
                 }
commit b224582aa3e7f0971035603515cf9c0e54ef299d
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Aug 26 21:08:47 2013 +0100

    Related: fdo#66435 enhance decker-wrap using Minimum raggedness algo
    
    Change-Id: Ifb7e6558d39499892a9e94bf1f89f014bacbdbc4

diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 4449181..e6e4aba 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -339,7 +339,84 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth )
     return aSize;
 }
 
-// -----------------------------------------------------------------------
+// Feel free to move this to some more general place for reuse
+// http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness
+// Mostly based on Alexey Frunze's nifty example at
+// http://stackoverflow.com/questions/9071205/balanced-word-wrap-minimum-raggedness-in-php
+namespace MinimumRaggednessWrap
+{
+    std::deque<size_t> GetEndOfLineIndexes(const std::vector<sal_Int32> rWidthsOf, sal_Int32 nLineWidth)
+    {
+        ++nLineWidth;
+
+        size_t nWidthsCount = rWidthsOf.size();
+        std::vector<sal_Int32> aCosts(nWidthsCount * nWidthsCount);
+
+        // cost function c(i, j) that computes the cost of a line consisting of
+        // the words Word[i] to Word[j]
+        for (size_t i = 0; i < nWidthsCount; ++i)
+        {
+            for (size_t j = 0; j < nWidthsCount; ++j)
+            {
+                if (j >= i)
+                {
+                    sal_Int32 c = nLineWidth - (j - i);
+                    for (size_t k = i; k <= j; ++k)
+                        c -= rWidthsOf[k];
+                    c = (c >= 0) ? c * c : SAL_MAX_INT32;
+                    aCosts[j * nWidthsCount + i] = c;
+                }
+                else
+                {
+                    aCosts[j * nWidthsCount + i] = SAL_MAX_INT32;
+                }
+            }
+        }
+
+        std::vector<sal_Int32> aFunction(nWidthsCount);
+        std::vector<sal_Int32> aWrapPoints(nWidthsCount);
+
+        // f(j) in aFunction[], collect wrap points in aWrapPoints[]
+        for (size_t j = 0; j < nWidthsCount; ++j)
+        {
+            aFunction[j] = aCosts[j * nWidthsCount];
+            if (aFunction[j] == SAL_MAX_INT32)
+            {
+                for (size_t k = 0; k < j; ++k)
+                {
+                    sal_Int32 s;
+                    if (aFunction[k] == SAL_MAX_INT32 || aCosts[j * nWidthsCount + k + 1] == SAL_MAX_INT32)
+                        s = SAL_MAX_INT32;
+                    else
+                        s = aFunction[k] + aCosts[j * nWidthsCount + k + 1];
+                    if (aFunction[j] > s)
+                    {
+                        aFunction[j] = s;
+                        aWrapPoints[j] = k + 1;
+                    }
+                }
+            }
+        }
+
+        std::deque<size_t> aSolution;
+
+        // no solution
+        if (aFunction[nWidthsCount - 1] == SAL_MAX_INT32)
+            return aSolution;
+
+        // optimal solution
+        size_t j = nWidthsCount - 1;
+        while (1)
+        {
+            aSolution.push_front(j);
+            if (!aWrapPoints[j])
+                break;
+            j = aWrapPoints[j] - 1;
+        }
+
+        return aSolution;
+    }
+};
 
 Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, long nHeight )
 {
@@ -394,6 +471,20 @@ Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, long nHe
         long            nMaxWidth = nWidth;
         sal_uInt16          nPos = 0;
 
+        //fdo#66435 throw Knuth/Tex minimum raggedness algorithm at the problem
+        //of ugly bare tabs on lines of their own
+
+        //collect widths
+        std::vector<sal_Int32> aWidths;
+        for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
+             it != mpTabCtrlData->maItemList.end(); ++it )
+        {
+            aWidths.push_back(ImplGetItemSize( &(*it), nMaxWidth ).Width());
+        }
+
+        //aBreakIndexes will contain the indexes of the last tab on each row
+        std::deque<size_t> aBreakIndexes(MinimumRaggednessWrap::GetEndOfLineIndexes(aWidths, nMaxWidth - nOffsetX - 2));
+
         if ( (mnMaxPageWidth > 0) && (mnMaxPageWidth < nMaxWidth) )
             nMaxWidth = mnMaxPageWidth;
         nMaxWidth -= GetItemsOffset().X();
@@ -403,21 +494,33 @@ Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, long nHe
         long            nLineWidthAry[100];
         sal_uInt16          nLinePosAry[101];
 
-        long nTotalWidth = nOffsetX;
-        for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
-             it != mpTabCtrlData->maItemList.end(); ++it )
-        {
-            nTotalWidth += ImplGetItemSize( &(*it), nMaxWidth ).Width();
-        }
-        long nWrapWidth = nWidth / ceil((double)nTotalWidth / nWidth);
-
         nLineWidthAry[0] = 0;
         nLinePosAry[0] = 0;
+        size_t nIndex = 0;
         for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
-             it != mpTabCtrlData->maItemList.end(); ++it )
+             it != mpTabCtrlData->maItemList.end(); ++it, ++nIndex )
         {
             aSize = ImplGetItemSize( &(*it), nMaxWidth );
 
+            bool bNewLine = false;
+            if (!aBreakIndexes.empty() && nIndex > aBreakIndexes.front())
+            {
+                aBreakIndexes.pop_front();
+                bNewLine = true;
+            }
+
+            if ( bNewLine && (nWidth > 2+nOffsetX) )
+            {
+                if ( nLines == 99 )
+                    break;
+
+                nX = nOffsetX;
+                nY += aSize.Height();
+                nLines++;
+                nLineWidthAry[nLines] = 0;
+                nLinePosAry[nLines] = nPos;
+            }
+
             Rectangle aNewRect( Point( nX, nY ), aSize );
             if ( mbSmallInvalidate && (it->maRect != aNewRect) )
                 mbSmallInvalidate = sal_False;
@@ -432,23 +535,6 @@ Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, long nHe
                 nCurLine = nLines;
 
             nPos++;
-
-            if ( (nX > nWrapWidth - 2) && (nWidth > 2+nOffsetX) )
-            {
-                if ( nLines == 99 )
-                    break;
-
-                nX  = nOffsetX;
-                nY += aSize.Height();
-                nLines++;
-                nLineWidthAry[nLines] = 0;
-                nLinePosAry[nLines] = nPos;
-            }
-        }
-
-        if ( nX == nOffsetX )
-        {
-            nLines--;
         }
 
         if ( nLines && !mpTabCtrlData->maItemList.empty() )


More information about the Libreoffice-commits mailing list