[ooo-build-commit] Branch 'ooo-build-3-1-1' - patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Dec 9 17:24:03 PST 2009


 patches/dev300/apply                                  |    7 
 patches/dev300/calc-perf-import-dbf-connectivity.diff |   99 +
 patches/dev300/calc-perf-import-dbf-sc.diff           |  968 ++++++++++++++++++
 patches/dev300/sal-strintern-speed-char-upper.diff    |  215 +++
 4 files changed, 1289 insertions(+)

New commits:
commit e0e0eca4f9011d97286448143b4232ea8a81a5c3
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Dec 9 17:50:15 2009 -0500

    Ported the DBF import performance patches from master.
    
    They are _disabled_ in the default build.
    
    * patches/dev300/apply:
    * patches/dev300/calc-perf-import-dbf-connectivity.diff:
    * patches/dev300/calc-perf-import-dbf-sc.diff:
    * patches/dev300/sal-strintern-speed-char-upper.diff:

diff --git a/patches/dev300/apply b/patches/dev300/apply
index 9ebc84b..418fd20 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3492,6 +3492,13 @@ calc-perf-page-and-manual-breaks-fwd-iterator.diff, n#503482, kohei
 # Refactor row height storage to speed up page break updates.
 calc-perf-speedup-pagebreak-update.diff, n#554955, kohei
 
+# string interning optimization for various IBM encoding types.
+sal-strintern-speed-char-upper.diff, kohei
+
+# speed optimization for dbf import.
+calc-perf-import-dbf-connectivity.diff, kohei
+calc-perf-import-dbf-sc.diff,           kohei
+
 [ AutoLayout ]
 sd-layoutcode.diff, cocofan
 offapi-layoutcode.diff, cocofan
diff --git a/patches/dev300/calc-perf-import-dbf-connectivity.diff b/patches/dev300/calc-perf-import-dbf-connectivity.diff
new file mode 100644
index 0000000..6395f84
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-connectivity.diff
@@ -0,0 +1,99 @@
+diff --git connectivity/source/drivers/dbase/DTable.cxx connectivity/source/drivers/dbase/DTable.cxx
+index 0db2f41..3498e39 100644
+--- connectivity/source/drivers/dbase/DTable.cxx
++++ connectivity/source/drivers/dbase/DTable.cxx
+@@ -686,50 +686,66 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+ 
+         if (nType == DataType::CHAR || nType == DataType::VARCHAR)
+         {
+-            char cLast = pData[nLen];
+-            pData[nLen] = 0;
+-            String aStr(pData,(xub_StrLen)nLen,m_eEncoding);
+-            aStr.EraseTrailingChars();
+-
+-            if ( aStr.Len() )
+-                *(_rRow->get())[i] = ::rtl::OUString(aStr);
+-            else// keine StringLaenge, dann NULL
++            sal_Int32 nLastPos = -1;
++            for (sal_Int32 k = 0; k < nLen; ++k)
++            {
++                if (pData[k] != ' ')
++                    // Record last non-empty position.
++                    nLastPos = k;
++            }
++            if (nLastPos < 0)
++            {
++                // Empty string.  Skip it.
+                 (_rRow->get())[i]->setNull();
+-                
+-            pData[nLen] = cLast;
++            }
++            else
++            {
++                // Commit the string.  Use intern() to ref-count it.
++                *(_rRow->get())[i] = ::rtl::OUString::intern(pData, static_cast<sal_Int32>(nLastPos+1), m_eEncoding);
++            }                
+         }
+         else
+         {
++            sal_Int32 nPos1 = -1, nPos2 = -1;
+             // Falls Nul-Zeichen im String enthalten sind, in Blanks umwandeln!
+             for (sal_Int32 k = 0; k < nLen; k++)
+             {
+                 if (pData[k] == '\0')
+                     pData[k] = ' ';
+-            }
+ 
+-            String aStr(pData, (xub_StrLen)nLen,m_eEncoding);		// Spaces am Anfang und am Ende entfernen:
+-            aStr.EraseLeadingChars();
+-            aStr.EraseTrailingChars();
++                if (pData[k] != ' ')
++                {
++                    if (nPos1 < 0)
++                        // first non-empty char position.
++                        nPos1 = k;
+ 
+-            if (!aStr.Len())
++                    // last non-empty char position.
++                    nPos2 = k;
++                }
++            }
++
++            if (nPos1 < 0)
+             {
++                // Empty string.  Skip it.
+                 nByteOffset += nLen;
+                 (_rRow->get())[i]->setNull();	// keine Werte -> fertig
+                 continue;
+             }
+ 
++            ::rtl::OUString aStr = ::rtl::OUString::intern(pData+nPos1, nPos2-nPos1+1, m_eEncoding);
++
+             switch (nType)
+             {
+                 case DataType::DATE:
+                 {
+-                    if (aStr.Len() != nLen)
++                    if (aStr.getLength() != nLen)
+                     {
+                         (_rRow->get())[i]->setNull();
+                         break;
+                     }
+-                    const sal_uInt16  nYear   = (sal_uInt16)aStr.Copy( 0, 4 ).ToInt32();
+-                    const sal_uInt16  nMonth  = (sal_uInt16)aStr.Copy( 4, 2 ).ToInt32();
+-                    const sal_uInt16  nDay    = (sal_uInt16)aStr.Copy( 6, 2 ).ToInt32();
++                    const sal_uInt16  nYear   = (sal_uInt16)aStr.copy( 0, 4 ).toInt32();
++                    const sal_uInt16  nMonth  = (sal_uInt16)aStr.copy( 4, 2 ).toInt32();
++                    const sal_uInt16  nDay    = (sal_uInt16)aStr.copy( 6, 2 ).toInt32();
+ 
+                     const ::com::sun::star::util::Date aDate(nDay,nMonth,nYear);
+                     *(_rRow->get())[i] = aDate;
+@@ -755,7 +772,7 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+                 break;
+                 case DataType::LONGVARCHAR:
+                 {
+-                    const long nBlockNo = aStr.ToInt32();	// Blocknummer lesen
++                    const long nBlockNo = aStr.toInt32();	// Blocknummer lesen
+                     if (nBlockNo > 0 && m_pMemoStream) // Daten aus Memo-Datei lesen, nur wenn
+                     {
+                         if ( !ReadMemo(nBlockNo, (_rRow->get())[i]->get()) )
diff --git a/patches/dev300/calc-perf-import-dbf-sc.diff b/patches/dev300/calc-perf-import-dbf-sc.diff
new file mode 100644
index 0000000..a5959fc
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-sc.diff
@@ -0,0 +1,968 @@
+diff --git sc/inc/column.hxx sc/inc/column.hxx
+index a39a958..48ed045 100644
+--- sc/inc/column.hxx
++++ sc/inc/column.hxx
+@@ -73,6 +73,7 @@ struct ScLineFlags;
+ struct ScMergePatternState;
+ class ScFlatBoolRowSegments;
+ struct ScSetStringParam;
++struct ScColWidthParam;
+ 
+ #define COLUMN_DELTA	4
+ 
+@@ -129,8 +130,16 @@ friend class ScHorizontalCellIterator;
+ friend class ScHorizontalAttrIterator;
+ 
+ public:
+-static BOOL bDoubleAlloc;			// fuer Import: Groesse beim Allozieren verdoppeln
++    static bool bDoubleAlloc;			// fuer Import: Groesse beim Allozieren verdoppeln
+ 
++    class DoubleAllocSwitch
++    {
++    public:
++        DoubleAllocSwitch(bool bNewVal = true);
++        ~DoubleAllocSwitch();
++    private:
++        bool mbOldVal;
++    };
+ public:
+                 ScColumn();
+                 ~ScColumn();
+@@ -370,7 +379,7 @@ public:
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, USHORT nOldWidth,
+                                     const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport );
++                                    const ScColWidthParam* pParam );
+     void		GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight,
+                                     OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+diff --git sc/inc/dbdocutl.hxx sc/inc/dbdocutl.hxx
+index 52d2680..d3cddf7 100644
+--- sc/inc/dbdocutl.hxx
++++ sc/inc/dbdocutl.hxx
+@@ -45,10 +45,20 @@ namespace com { namespace sun { namespace star { namespace sdbc {
+ class ScDatabaseDocUtil
+ {
+ public:
++    /** 
++     * Detailed information on single string value.
++     */
++    struct StrData
++    {
++        bool        mbSimpleText;
++        sal_uInt32  mnStrLength;
++
++        StrData();
++    };
+     static void PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+                         const ::com::sun::star::uno::Reference<
+                             ::com::sun::star::sdbc::XRow>& xRow, long nRowPos,
+-                        long nType, BOOL bCurrency, BOOL* pSimpleFlag = NULL );
++                        long nType, BOOL bCurrency, StrData* pStrData = NULL );
+ };
+ 
+ #endif
+diff --git sc/inc/dociter.hxx sc/inc/dociter.hxx
+index d5d4235..bd40623 100644
+--- sc/inc/dociter.hxx
++++ sc/inc/dociter.hxx
+@@ -36,12 +36,16 @@
+ #include "global.hxx"
+ #include "scdllapi.h"
+ 
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
+ class ScDocument;
+ class ScBaseCell;
+ class ScPatternAttr;
+ class ScAttrArray;
+ class ScAttrIterator;
+ class ScRange;
++class ScFlatBoolRowSegments;
+ 
+ class ScDocumentIterator				// alle nichtleeren Zellen durchgehen
+ {
+@@ -451,6 +455,42 @@ public:
+     const ScBaseCell*		GetCell() const			{ return pFoundCell; }
+ };
+ 
++// ============================================================================
++
++class ScDocRowHeightUpdater
++{
++public:
++    struct TabRanges
++    {
++        SCTAB mnTab;
++        ::boost::shared_ptr<ScFlatBoolRowSegments> mpRanges;
++
++        TabRanges();
++        TabRanges(SCTAB nTab);
++    };
++
++    /** 
++     * Passing a NULL pointer to pTabRangesArray forces the heights of all 
++     * rows in all tables to be updated. 
++     */
++    explicit ScDocRowHeightUpdater(
++        ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, 
++        const ::std::vector<TabRanges>* pTabRangesArray = NULL);
++
++    void update();
++
++private:
++    void updateAll();
++
++private:
++    ScDocument& mrDoc;
++    OutputDevice* mpOutDev;
++    double mfPPTX;
++    double mfPPTY;
++    const ::std::vector<TabRanges>* mpTabRangesArray;
++};
++
++
+ #endif
+ 
+ 
+diff --git sc/inc/docparam.hxx sc/inc/docparam.hxx
+new file mode 100644
+index 0000000..e273c01
+--- /dev/null
++++ sc/inc/docparam.hxx
+@@ -0,0 +1,47 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef SC_DOCPARAM_HXX
++#define SC_DOCPARAM_HXX
++
++#include "address.hxx"
++
++// Let's put here misc structures that get passed to ScDocument's methods.
++
++struct ScColWidthParam
++{
++    SCROW       mnMaxTextRow;
++    sal_uInt32  mnMaxTextLen;
++    bool        mbSimpleText;
++
++    ScColWidthParam();
++};
++
++#endif
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index 26d19a9..1ab39fd 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -143,6 +143,8 @@ struct ScLookupCacheMapImpl;
+ struct ScClipParam;
+ struct ScClipRangeNameData;
+ struct ScSetStringParam;
++class ScDocRowHeightUpdater;
++struct ScColWidthParam;
+ 
+ namespace com { namespace sun { namespace star {
+     namespace lang {
+@@ -245,6 +247,7 @@ friend class ScHorizontalCellIterator;
+ friend class ScHorizontalAttrIterator;
+ friend class ScDocAttrIterator;
+ friend class ScAttrRectIterator;
++friend class ScDocRowHeightUpdater;
+ #if OLD_PIVOT_IMPLEMENTATION
+ friend class ScPivot;
+ #endif
+@@ -1264,7 +1267,7 @@ public:
+                                         const Fraction& rZoomX, const Fraction& rZoomY,
+                                         BOOL bFormula,
+                                         const ScMarkData* pMarkData = NULL,
+-                                        BOOL bSimpleTextImport = FALSE );
++                                        const ScColWidthParam* pParam = NULL );
+     SC_DLLPUBLIC BOOL			SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nExtra,
+                                         OutputDevice* pDev,
+                                         double nPPTX, double nPPTY,
+diff --git sc/inc/segmenttree.hxx sc/inc/segmenttree.hxx
+index 9b9d753..3199f7d 100644
+--- sc/inc/segmenttree.hxx
++++ sc/inc/segmenttree.hxx
+@@ -63,6 +63,16 @@ public:
+         bool    mbCurValue;
+     };
+ 
++    class RangeIterator
++    {
++    public:
++        explicit RangeIterator(ScFlatBoolRowSegments& rSegs);
++        bool getFirst(RangeData& rRange);
++        bool getNext(RangeData& rRange);
++    private:
++        ScFlatBoolRowSegments& mrSegs;
++    };
++
+     ScFlatBoolRowSegments();
+     ~ScFlatBoolRowSegments();
+ 
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index db301be..a71ac29 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -87,6 +87,7 @@ class ScFlatUInt16RowSegments;
+ class ScFlatBoolRowSegments;
+ class ScFlatBoolColSegments;
+ struct ScSetStringParam;
++struct ScColWidthParam;
+ 
+ class ScTable
+ {
+@@ -573,7 +574,7 @@ public:
+                                     double nPPTX, double nPPTY,
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport );
++                                    const ScColWidthParam* pParam );
+     BOOL		SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT nExtra,
+                                     OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx
+index 76ecf13..0702976 100644
+--- sc/source/core/data/column.cxx
++++ sc/source/core/data/column.cxx
+@@ -70,8 +70,20 @@ inline BOOL IsAmbiguousScriptNonZero( BYTE nScript )
+              nScript != 0 );
+ }
+ 
+-// -----------------------------------------------------------------------------------------
++// ----------------------------------------------------------------------------
+ 
++ScColumn::DoubleAllocSwitch::DoubleAllocSwitch(bool bNewVal) :
++    mbOldVal(ScColumn::bDoubleAlloc)
++{
++    ScColumn::bDoubleAlloc = bNewVal;
++}
++
++ScColumn::DoubleAllocSwitch::~DoubleAllocSwitch()
++{
++    ScColumn::bDoubleAlloc = mbOldVal;
++}
++
++// ----------------------------------------------------------------------------
+ 
+ ScColumn::ScColumn() :
+     nCol( 0 ),
+diff --git sc/source/core/data/column2.cxx sc/source/core/data/column2.cxx
+index 6295c28..cd04467 100644
+--- sc/source/core/data/column2.cxx
++++ sc/source/core/data/column2.cxx
+@@ -70,6 +70,7 @@
+ #include "dbcolect.hxx"
+ #include "fillinfo.hxx"
+ #include "segmenttree.hxx"
++#include "docparam.hxx"
+ 
+ #include <math.h>
+ 
+@@ -637,10 +638,10 @@ long ScColumn::GetSimpleTextNeededSize( SCSIZE nIndex, OutputDevice* pDev,
+ }
+ 
+ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
+-                                        const Fraction& rZoomX, const Fraction& rZoomY,
+-                                        BOOL bFormula, USHORT nOldWidth,
+-                                        const ScMarkData* pMarkData,
+-                                        BOOL bSimpleTextImport )
++                                     const Fraction& rZoomX, const Fraction& rZoomY,
++                                     BOOL bFormula, USHORT nOldWidth,
++                                     const ScMarkData* pMarkData,
++                                     const ScColWidthParam* pParam )
+ {
+     if (nCount == 0)
+         return nOldWidth;
+@@ -650,7 +651,7 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+ 
+     SCSIZE nIndex;
+     ScMarkedDataIter aDataIter(this, pMarkData, TRUE);
+-    if ( bSimpleTextImport )
++    if ( pParam && pParam->mbSimpleText )
+     {	// alles eins bis auf NumberFormate
+         const ScPatternAttr* pPattern = GetPattern( 0 );
+         Font aFont;
+@@ -661,19 +662,44 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+         long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
+                         (long) ( pMargin->GetRightMargin() * nPPTX );
+ 
+-        while (aDataIter.Next( nIndex ))
++        // Try to find the row that has the longest string, and measure the width of that string.
++        SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
++        ULONG nFormat = pPattern->GetNumberFormat( pFormatter );
++        String aLongStr;
++        Color* pColor;
++        if (pParam->mnMaxTextRow >= 0)
+         {
+-            USHORT nThis = (USHORT) (GetSimpleTextNeededSize( nIndex, pDev,
+-                TRUE ) + nMargin);
+-            if (nThis)
++            ScBaseCell* pCell = GetCell(pParam->mnMaxTextRow);
++            ScCellFormat::GetString(
++                pCell, nFormat, aLongStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++        }
++        else
++        {
++            xub_StrLen nLongLen = 0;
++            while (aDataIter.Next(nIndex))
+             {
+-                if (nThis>nWidth || !bFound)
++                if (nIndex >= nCount)
++                    // Out-of-bound reached.  No need to keep going.
++                    break;
++    
++                ScBaseCell* pCell = pItems[nIndex].pCell;
++                String aValStr;
++                ScCellFormat::GetString(
++                    pCell, nFormat, aValStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++                
++                if (aValStr.Len() > nLongLen)
+                 {
+-                    nWidth = nThis;
+-                    bFound = TRUE;
++                    nLongLen = aValStr.Len();
++                    aLongStr = aValStr;
+                 }
+             }
+         }
++
++        if (aLongStr.Len())
++        {    
++            nWidth = pDev->GetTextWidth(aLongStr) + static_cast<USHORT>(nMargin);
++            bFound = true;
++        }
+     }
+     else
+     {
+diff --git sc/source/core/data/column3.cxx sc/source/core/data/column3.cxx
+index a37a53e..c4e3748 100644
+--- sc/source/core/data/column3.cxx
++++ sc/source/core/data/column3.cxx
+@@ -68,7 +68,7 @@ extern const ScFormulaCell* pLastFormulaTreeTop;	// in cellform.cxx
+ using namespace formula;
+ // STATIC DATA -----------------------------------------------------------
+ 
+-BOOL ScColumn::bDoubleAlloc = FALSE;	// fuer Import: Groesse beim Allozieren verdoppeln
++bool ScColumn::bDoubleAlloc = FALSE;    // fuer Import: Groesse beim Allozieren verdoppeln
+ 
+ 
+ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
+diff --git sc/source/core/data/dbdocutl.cxx sc/source/core/data/dbdocutl.cxx
+index 707f0da..a1146ad 100644
+--- sc/source/core/data/dbdocutl.cxx
++++ sc/source/core/data/dbdocutl.cxx
+@@ -49,12 +49,19 @@ using namespace ::com::sun::star;
+ 
+ #define D_TIMEFACTOR              86400.0
+ 
+-// -----------------------------------------------------------------------
++// ----------------------------------------------------------------------------
++
++ScDatabaseDocUtil::StrData::StrData() :
++    mbSimpleText(true), mnStrLength(0)
++{
++}
++
++// ----------------------------------------------------------------------------
+ 
+ // static
+ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                 const uno::Reference<sdbc::XRow>& xRow, long nRowPos,
+-                                long nType, BOOL bCurrency, BOOL* pSimpleFlag )
++                                long nType, BOOL bCurrency, StrData* pStrData )
+ {
+     String aString;
+     double nVal = 0.0;
+@@ -188,8 +195,11 @@ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB
+         if (aString.Len())
+         {
+             pCell = ScBaseCell::CreateTextCell( aString, pDoc );
+-            if ( pSimpleFlag && pCell->GetCellType() == CELLTYPE_EDIT )
+-                *pSimpleFlag = FALSE;
++            if (pStrData)
++            {    
++                pStrData->mbSimpleText = pCell->GetCellType() != CELLTYPE_EDIT;
++                pStrData->mnStrLength = aString.Len();
++            }
+         }
+         else
+             pCell = NULL;
+diff --git sc/source/core/data/dociter.cxx sc/source/core/data/dociter.cxx
+index 055c64f..b8dc325 100644
+--- sc/source/core/data/dociter.cxx
++++ sc/source/core/data/dociter.cxx
+@@ -46,6 +46,12 @@
+ #include "patattr.hxx"
+ #include "docoptio.hxx"
+ #include "cellform.hxx"
++#include "segmenttree.hxx"
++#include "progress.hxx"
++#include "globstr.hrc"
++#include "tools/fract.hxx"
++
++using ::std::vector;
+  
+ 
+ // STATIC DATA -----------------------------------------------------------
+@@ -1801,3 +1805,96 @@ const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
+     return NULL;		// is nix mehr
+ }
+ 
++// ============================================================================
++
++ScDocRowHeightUpdater::TabRanges::TabRanges() :
++    mnTab(0), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::TabRanges::TabRanges(SCTAB nTab) :
++    mnTab(nTab), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
++    mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
++{
++}
++
++void ScDocRowHeightUpdater::update()
++{
++    if (!mpTabRangesArray || mpTabRangesArray->empty())
++    {
++        // No ranges defined.  Update all rows in all tables.
++        updateAll();
++        return;
++    }
++
++    sal_uInt32 nCellCount = 0;
++    vector<TabRanges>::const_iterator itr = mpTabRangesArray->begin(), itrEnd = mpTabRangesArray->end();
++    for (; itr != itrEnd; ++itr)
++    {
++        ScFlatBoolRowSegments::RangeData aData;
++        ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++        for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++        {
++            if (!aData.mbValue)
++                continue;
++
++            nCellCount += aData.mnRow2 - aData.mnRow1 + 1;
++        }
++    }
++
++    ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++    Fraction aZoom(1, 1);
++    itr = mpTabRangesArray->begin();
++    sal_uInt32 nProgressStart = 0;
++    for (; itr != itrEnd; ++itr)
++    {
++        SCTAB nTab = itr->mnTab;
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        ScFlatBoolRowSegments::RangeData aData;
++        ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++        for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++        {
++            if (!aData.mbValue)
++                continue;
++
++            mrDoc.pTab[nTab]->SetOptimalHeight(
++                aData.mnRow1, aData.mnRow2, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++            nProgressStart += aData.mnRow2 - aData.mnRow1 + 1;
++        }
++    }
++}
++
++void ScDocRowHeightUpdater::updateAll()
++{
++    sal_uInt32 nCellCount = 0;
++    for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++    {
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        nCellCount += mrDoc.pTab[nTab]->GetWeightedCount();
++    }
++
++    ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++    Fraction aZoom(1, 1);
++    ULONG nProgressStart = 0;
++    for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++    {
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        mrDoc.pTab[nTab]->SetOptimalHeight(
++            0, MAXROW, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++        nProgressStart += mrDoc.pTab[nTab]->GetWeightedCount();
++    }
++}
+diff --git sc/source/core/data/docparam.cxx sc/source/core/data/docparam.cxx
+new file mode 100644
+index 0000000..0644dd6
+--- /dev/null
++++ sc/source/core/data/docparam.cxx
+@@ -0,0 +1,40 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_sc.hxx"
++
++// INCLUDE ---------------------------------------------------------------
++
++#include "docparam.hxx"
++
++ScColWidthParam::ScColWidthParam() :
++    mnMaxTextRow(-1), mnMaxTextLen(0), mbSimpleText(true) {}
++
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 579c99a..4285017 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3078,14 +3078,14 @@ ULONG ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab ) const
+ 
+ 
+ USHORT ScDocument::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev,
+-                                        double nPPTX, double nPPTY,
+-                                        const Fraction& rZoomX, const Fraction& rZoomY,
+-                                        BOOL bFormula, const ScMarkData* pMarkData,
+-                                        BOOL bSimpleTextImport )
++                                       double nPPTX, double nPPTY,
++                                       const Fraction& rZoomX, const Fraction& rZoomY,
++                                       BOOL bFormula, const ScMarkData* pMarkData,
++                                       const ScColWidthParam* pParam )
+ {
+     if ( ValidTab(nTab) && pTab[nTab] )
+         return pTab[nTab]->GetOptimalColWidth( nCol, pDev, nPPTX, nPPTY,
+-            rZoomX, rZoomY, bFormula, pMarkData, bSimpleTextImport );
++            rZoomX, rZoomY, bFormula, pMarkData, pParam );
+     DBG_ERROR("Falsche Tabellennummer");
+     return 0;
+ }
+diff --git sc/source/core/data/makefile.mk sc/source/core/data/makefile.mk
+index 4ac58a9..01ad5fa 100644
+--- sc/source/core/data/makefile.mk
++++ sc/source/core/data/makefile.mk
+@@ -74,6 +74,7 @@ SLOFILES =  \
+     $(SLO)$/documen8.obj \
+     $(SLO)$/documen9.obj \
+     $(SLO)$/document.obj \
++    $(SLO)$/docparam.obj \
+         $(SLO)$/dpcachetable.obj \
+         $(SLO)$/dpdimsave.obj \
+         $(SLO)$/dpgroup.obj \
+diff --git sc/source/core/data/segmenttree.cxx sc/source/core/data/segmenttree.cxx
+index 98c5032..b86aca8 100644
+--- sc/source/core/data/segmenttree.cxx
++++ sc/source/core/data/segmenttree.cxx
+@@ -66,9 +66,14 @@ public:
+ 
+     SCROW findLastNotOf(ValueType nValue) const;
+ 
++    // range iteration
++    bool getFirst(RangeData& rData);
++    bool getNext(RangeData& rData);
++
+ private:
+     typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
+     fst_type maSegments;
++    typename fst_type::const_iterator maItr;
+ };
+ 
+ template<typename _ValueType, typename _ExtValueType>
+@@ -175,6 +180,31 @@ SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType
+     return nPos;
+ }
+ 
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
++{
++    maItr = maSegments.begin();
++    return getNext(rData);
++}
++
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
++{
++    typename fst_type::const_iterator itrEnd = maSegments.end();
++    if (maItr == itrEnd)
++        return false;
++
++    rData.mnPos1 = maItr->first;
++    rData.mnValue = maItr->second;
++
++    ++maItr;
++    if (maItr == itrEnd)
++        return false;
++
++    rData.mnPos2 = maItr->first - 1;
++    return true;
++}
++
+ // ============================================================================
+ 
+ class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
+@@ -245,6 +275,37 @@ SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
+ 
+ // ----------------------------------------------------------------------------
+ 
++ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
++    mrSegs(rSegs)
++{
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
++{
++    ScFlatBoolSegmentsImpl::RangeData aData;
++    if (!mrSegs.mpImpl->getFirst(aData))
++        return false;
++
++    rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
++    rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
++    rRange.mbValue = static_cast<bool>(aData.mnValue);
++    return true;
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
++{
++    ScFlatBoolSegmentsImpl::RangeData aData;
++    if (!mrSegs.mpImpl->getNext(aData))
++        return false;
++
++    rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
++    rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
++    rRange.mbValue = static_cast<bool>(aData.mnValue);
++    return true;
++}
++
++// ----------------------------------------------------------------------------
++
+ ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+     mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
+ {
+diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
+index 5319b1a..3294c06 100644
+--- sc/source/core/data/table1.cxx
++++ sc/source/core/data/table1.cxx
+@@ -287,10 +287,10 @@ USHORT ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport )
++                                    const ScColWidthParam* pParam )
+ {
+     return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
+-        bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
++        bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
+ }
+ 
+ long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
+diff --git sc/source/ui/docshell/dbdocimp.cxx sc/source/ui/docshell/dbdocimp.cxx
+index cf25c03..895816d 100644
+--- sc/source/ui/docshell/dbdocimp.cxx
++++ sc/source/ui/docshell/dbdocimp.cxx
+@@ -271,7 +271,7 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+     // ImportDoc - also used for Redo
+     ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
+     pImportDoc->InitUndo( pDoc, nTab, nTab );
+-    ScColumn::bDoubleAlloc = TRUE;
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+ 
+     //
+     //	get data from database into import document
+@@ -463,7 +463,6 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+         DBG_ERROR("Unexpected exception in database");
+     }
+ 
+-    ScColumn::bDoubleAlloc = FALSE;
+     pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
+ 
+     //
+diff --git sc/source/ui/docshell/docsh.cxx sc/source/ui/docshell/docsh.cxx
+index a3d74c8..9a007ce 100644
+--- sc/source/ui/docshell/docsh.cxx
++++ sc/source/ui/docshell/docsh.cxx
+@@ -121,9 +121,11 @@
+ #include "warnpassword.hxx"
+ #include "optsolver.hxx"
+ #include "tabprotection.hxx"
++#include "docparam.hxx"
+ 
+ #include "docsh.hxx"
+ #include "docshimp.hxx"
++#include "sizedev.hxx"
+ #include <rtl/logfile.hxx>
+ 
+ #include <comphelper/processfactory.hxx>
+@@ -133,12 +135,18 @@
+ #include <com/sun/star/document/VbaEventId.hpp>
+ #include <basic/sbstar.hxx>
+ #include <basic/basmgr.hxx>
++
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
+ using namespace com::sun::star;
+ using namespace com::sun::star::document::VbaEventId;
+ 
+ using namespace com::sun::star;
+ using ::rtl::OUString;
+ using ::rtl::OUStringBuffer;
++using ::boost::shared_ptr;
++using ::std::vector;
+ 
+ // STATIC DATA -----------------------------------------------------------
+ 
+@@ -948,12 +956,13 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+     // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
+     BOOL bSetColWidths = FALSE;
+     BOOL bSetSimpleTextColWidths = FALSE;
+-    BOOL bSimpleColWidth[MAXCOLCOUNT];
+-    memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(BOOL) );
++    ScColWidthParam aColWidthParam[MAXCOLCOUNT];
+     ScRange aColWidthRange;
+     // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
+     BOOL bSetRowHeights = FALSE;
+ 
++    vector<ScDocRowHeightUpdater::TabRanges> aRecalcRowRangesArray;
++
+     aConvFilterName.Erase(); //@ #BugId 54198
+ 
+     //	Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
+@@ -1152,8 +1161,10 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+                 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
+             }
+ 
++            ScDocRowHeightUpdater::TabRanges aRecalcRanges(0);
+             ULONG eError = DBaseImport( rMedium.GetPhysicalName(),
+-                    ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
++                    ScGlobal::GetCharsetValue(sItStr), aColWidthParam, *aRecalcRanges.mpRanges );
++            aRecalcRowRangesArray.push_back(aRecalcRanges);
+ 
+             if (eError != eERR_OK)
+             {
+@@ -1167,12 +1178,6 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+             aColWidthRange.aStart.SetRow( 1 );	// Spaltenheader nicht
+             bSetColWidths = TRUE;
+             bSetSimpleTextColWidths = TRUE;
+-            // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
+-            for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
+-            {
+-                if ( !bSimpleColWidth[nCol] )
+-                    bSetRowHeights = TRUE;
+-            }
+         }
+         else if (aFltName.EqualsAscii(pFilterDif))
+         {
+@@ -1386,9 +1391,12 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+             {
+                 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
+                 {
++                    if (!bSetSimpleTextColWidths)
++                        aColWidthParam[nCol].mbSimpleText = false;
++
+                     USHORT nWidth = aDocument.GetOptimalColWidth(
+                         nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark,
+-                        (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
++                        &aColWidthParam[nCol] );
+                     aDocument.SetColWidth( nCol, nTab,
+                         nWidth + (USHORT)ScGlobal::nLastColWidthExtra );
+                 }
+@@ -1400,11 +1408,25 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ //					nPPTX, nPPTY, aZoom, aZoom, FALSE );
+ //			}
+         }
+-        if ( bSetRowHeights )
+-            UpdateAllRowHeights();		// with vdev or printer, depending on configuration
++
++        if (bSetRowHeights)
++        {
++            // Update all rows in all tables.
++            ScSizeDeviceProvider aProv(this);
++            ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), NULL);
++            aUpdater.update();
++        }
++        else if (!aRecalcRowRangesArray.empty())
++        {
++            // Update only specified row ranges for better performance.
++            ScSizeDeviceProvider aProv(this);
++            ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &aRecalcRowRangesArray);
++            aUpdater.update();
++        }
+     }
+     FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
+ 
++
+     // #73762# invalidate eventually temporary table areas
+     if ( bRet )
+         aDocument.InvalidateTableArea();
+diff --git sc/source/ui/docshell/docsh8.cxx sc/source/ui/docshell/docsh8.cxx
+index c01cda9..fbc8976 100644
+--- sc/source/ui/docshell/docsh8.cxx
++++ sc/source/ui/docshell/docsh8.cxx
+@@ -85,6 +85,8 @@
+ #include "patattr.hxx"
+ #include "scitems.hxx"
+ #include "docpool.hxx"
++#include "segmenttree.hxx"
++#include "docparam.hxx"
+ 
+ #include <vector>
+ 
+@@ -248,9 +250,11 @@ static void lcl_setScalesToColumns(ScDocument& rDoc, const vector<long>& rScales
+     }
+ }
+ 
+-ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+-                                BOOL bSimpleColWidth[MAXCOLCOUNT] )
++ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet, 
++                               ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc )
+ {
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
++
+     ULONG nErr = eERR_OK;
+     long i;
+ 
+@@ -407,16 +411,33 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+         BOOL bEnd = FALSE;
+         while ( !bEnd && xRowSet->next() )
+         {
++            bool bSimpleRow = true;
+             if ( nRow <= MAXROW )
+             {
+                 SCCOL nCol = 0;
+                 for (i=0; i<nColCount; i++)
+                 {
++                    ScDatabaseDocUtil::StrData aStrData;
+                     ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
+                                                 xRow, i+1, pTypeArr[i], FALSE,
+-                                                &bSimpleColWidth[nCol] );
++                                                &aStrData );
++
++                    if (aStrData.mnStrLength > aColWidthParam[nCol].mnMaxTextLen)
++                    {
++                        aColWidthParam[nCol].mnMaxTextLen = aStrData.mnStrLength;
++                        aColWidthParam[nCol].mnMaxTextRow = nRow;
++                    }
++
++                    if (!aStrData.mbSimpleText)
++                    {    
++                        bSimpleRow = false;
++                        aColWidthParam[nCol].mbSimpleText = false;
++                    }
++
+                     ++nCol;
+                 }
++                if (!bSimpleRow)
++                    rRowHeightsRecalc.setTrue(nRow, nRow);
+                 ++nRow;
+             }
+             else		// past the end of the spreadsheet
+diff --git sc/source/ui/docshell/impex.cxx sc/source/ui/docshell/impex.cxx
+index 573443d..b036ab4 100644
+--- sc/source/ui/docshell/impex.cxx
++++ sc/source/ui/docshell/impex.cxx
+@@ -1081,8 +1081,7 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+     if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+         rStrm.StartReadingUnicodeText();
+ 
+-    BOOL bOld = ScColumn::bDoubleAlloc;
+-    ScColumn::bDoubleAlloc = TRUE;
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+ 
+     SCCOL nStartCol = aRange.aStart.Col();
+     SCCOL nEndCol = aRange.aEnd.Col();
+@@ -1283,7 +1282,6 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+         bDetermineRange = !bDetermineRange;     // toggle
+     } while (!bDetermineRange);
+ 
+-    ScColumn::bDoubleAlloc = bOld;
+     pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );
+ 
+     delete pEnglishTransliteration;
+diff --git sc/source/ui/inc/docsh.hxx sc/source/ui/inc/docsh.hxx
+index 50f1920..24658d7 100644
+--- sc/source/ui/inc/docsh.hxx
++++ sc/source/ui/inc/docsh.hxx
+@@ -76,6 +76,8 @@ class VirtualDevice;
+ class ScImportOptions;
+ class ScDocShellModificator;
+ class ScOptSolverSave;
++class ScFlatBoolRowSegments;
++struct ScColWidthParam;
+ 
+ namespace sfx2 { class FileDialogHelper; }
+ struct DocShell_Impl;
+@@ -156,7 +158,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
+     SC_DLLPRIVATE SCTAB			GetSaveTab();
+ 
+     SC_DLLPRIVATE ULONG			DBaseImport( const String& rFullFileName, CharSet eCharSet,
+-                                 BOOL bSimpleColWidth[MAXCOLCOUNT] );
++                                             ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc );
+     SC_DLLPRIVATE ULONG			DBaseExport( const String& rFullFileName, CharSet eCharSet,
+                                  BOOL& bHasMemo );
+ 
diff --git a/patches/dev300/sal-strintern-speed-char-upper.diff b/patches/dev300/sal-strintern-speed-char-upper.diff
new file mode 100644
index 0000000..5f2fdb3
--- /dev/null
+++ b/patches/dev300/sal-strintern-speed-char-upper.diff
@@ -0,0 +1,215 @@
+diff --git sal/rtl/source/ustring.c sal/rtl/source/ustring.c
+index b545ff4..c0cf7b5 100644
+--- sal/rtl/source/ustring.c
++++ sal/rtl/source/ustring.c
+@@ -818,23 +818,53 @@ void SAL_CALL rtl_uString_internConvert( rtl_uString   ** newStr,
+     { // try various optimisations
+         if ( len < 0 )
+             len = strlen( str );
+-        if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
++        switch ( eTextEncoding )
+         {
+-            int i;
+-            rtl_uString *pScratch;
+-            pScratch = alloca( sizeof( rtl_uString )
+-                               + len * sizeof (IMPL_RTL_STRCODE ) );
+-            for (i = 0; i < len; i++)
++            case RTL_TEXTENCODING_ASCII_US:
+             {
+-                /* Check ASCII range */
+-                OSL_ENSURE( ((unsigned char)str[i]) <= 127,
+-                            "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
+-                pScratch->buffer[i] = str[i];
++                int i;
++                rtl_uString *pScratch;
++                pScratch = alloca( sizeof( rtl_uString )
++                                   + len * sizeof (IMPL_RTL_STRCODE ) );
++                for (i = 0; i < len; i++)
++                {
++                    /* Check ASCII range */
++                    OSL_ENSURE( ((unsigned char)str[i]) <= 127,
++                                "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
++                    pScratch->buffer[i] = str[i];
++                }
++                pScratch->length = len;
++                rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
++                return;
++            }
++            case RTL_TEXTENCODING_IBM_437:
++            case RTL_TEXTENCODING_IBM_850:
++            case RTL_TEXTENCODING_IBM_860:
++            case RTL_TEXTENCODING_IBM_861:
++            case RTL_TEXTENCODING_IBM_863:
++            case RTL_TEXTENCODING_IBM_865:
++            {
++                rtl_uString *pScratch;
++                rtl_TextToUnicodeConverter hConverter;
++                sal_Size nDestChars, nSrcBytes;
++                sal_uInt32 nInfo;
++
++                hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
++                pScratch = alloca( sizeof(rtl_uString) + len * sizeof (IMPL_RTL_STRCODE) );
++
++                nDestChars = rtl_convertTextToUnicode(
++                    hConverter, 0, str, len, pScratch->buffer, len, convertFlags, &nInfo, &nSrcBytes );
++                pScratch->length = len;
++
++                if (pInfo)
++                    *pInfo = nInfo;
++
++                rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
++                rtl_destroyTextToUnicodeConverter( hConverter );
++                return;
+             }
+-            pScratch->length = len;
+-            rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
+-            return;
+         }
++
+         /* FIXME: we want a nice UTF-8 / alloca shortcut here */
+     }
+ 
+diff --git sal/textenc/tcvtbyte.c sal/textenc/tcvtbyte.c
+index be39b8e..ca5571e 100644
+--- sal/textenc/tcvtbyte.c
++++ sal/textenc/tcvtbyte.c
+@@ -643,6 +643,47 @@ sal_Size ImplCharToUnicode( const ImplTextConverterData* pData,
+ 
+ /* ----------------------------------------------------------------------- */
+ 
++sal_Size ImplUpperCharToUnicode( const ImplTextConverterData* pData,
++                            void* pContext,
++                            const sal_Char* pSrcBuf, sal_Size nSrcBytes,
++                            sal_Unicode* pDestBuf, sal_Size nDestChars,
++                            sal_uInt32 nFlags, sal_uInt32* pInfo,
++                            sal_Size* pSrcCvtBytes )
++{
++    sal_uChar                   c;
++    sal_Unicode                 cConv;
++    const ImplByteConvertData*  pConvertData = (const ImplByteConvertData*)pData;
++    sal_Unicode*                pEndDestBuf;
++    const sal_Char*             pEndSrcBuf;
++
++    (void) pContext; /* unused */
++    (void) nFlags;   /* unused */
++
++    *pInfo = 0;
++    pEndDestBuf = pDestBuf+nDestChars;
++    pEndSrcBuf  = pSrcBuf+nSrcBytes;
++    while ( pSrcBuf < pEndSrcBuf )
++    {
++        c = (sal_uChar)*pSrcBuf;
++        if (c < 0x80)
++            cConv = c;
++        else
++            // c <= 0xFF is implied.
++            cConv = pConvertData->mpToUniTab1[c - 0x80];
++
++        // No need to handle cConv == 0 since that never happens.
++
++        *pDestBuf = cConv;
++        pDestBuf++;
++        pSrcBuf++;
++    }
++
++    *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf);
++    return (nDestChars - (pEndDestBuf-pDestBuf));
++}
++
++/* ----------------------------------------------------------------------- */
++
+ // Writes 0--2 characters to dest:
+ static int ImplConvertUnicodeCharToChar(
+     const ImplByteConvertData* pConvertData, sal_Unicode c, sal_Char * dest )
+diff --git sal/textenc/tcvtlat1.tab sal/textenc/tcvtlat1.tab
+index 4bc77f6..86e7b06 100644
+--- sal/textenc/tcvtlat1.tab
++++ sal/textenc/tcvtlat1.tab
+@@ -191,7 +191,7 @@ static ImplByteConvertData const aImplIBM437ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM437TextEncodingData
+     = { { &aImplIBM437ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -325,7 +325,7 @@ static ImplByteConvertData const aImplIBM850ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM850TextEncodingData
+     = { { &aImplIBM850ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -498,7 +498,7 @@ static ImplByteConvertData const aImplIBM860ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM860TextEncodingData
+     = { { &aImplIBM860ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -673,7 +673,7 @@ static ImplByteConvertData const aImplIBM861ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM861TextEncodingData
+     = { { &aImplIBM861ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -848,7 +848,7 @@ static ImplByteConvertData const aImplIBM863ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM863TextEncodingData
+     = { { &aImplIBM863ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -1023,7 +1023,7 @@ static ImplByteConvertData const aImplIBM865ByteCvtData =
+ 
+ static ImplTextEncodingData const aImplIBM865TextEncodingData
+     = { { &aImplIBM865ByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -1563,7 +1563,7 @@ static ImplByteConvertData const aImplAPPLEICELANDByteCvtData =
+ 
+ static ImplTextEncodingData const aImplAPPLEICELANDTextEncodingData
+     = { { &aImplAPPLEICELANDByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+@@ -1710,7 +1710,7 @@ static ImplByteConvertData const aImplAPPLEROMANByteCvtData =
+ 
+ static ImplTextEncodingData const aImplAPPLEROMANTextEncodingData
+     = { { &aImplAPPLEROMANByteCvtData,
+-          ImplCharToUnicode,
++          ImplUpperCharToUnicode,
+           ImplUnicodeToChar,
+           NULL,
+           NULL,
+diff --git sal/textenc/tenchelp.h sal/textenc/tenchelp.h
+index 16affcd..6c0a930 100644
+--- sal/textenc/tenchelp.h
++++ sal/textenc/tenchelp.h
+@@ -233,6 +233,11 @@ sal_Size ImplCharToUnicode( const ImplTextConverterData* pData, void* pContext,
+                             const sal_Char* pSrcBuf, sal_Size nSrcBytes,
+                             sal_Unicode* pDestBuf, sal_Size nDestChars,
+                             sal_uInt32 nFlags, sal_uInt32* pInfo, sal_Size* pSrcCvtBytes );
++/** For those encodings only with unicode range of 0x80 to 0xFF. */
++sal_Size ImplUpperCharToUnicode( const ImplTextConverterData* pData, void* pContext,
++                            const sal_Char* pSrcBuf, sal_Size nSrcBytes,
++                            sal_Unicode* pDestBuf, sal_Size nDestChars,
++                            sal_uInt32 nFlags, sal_uInt32* pInfo, sal_Size* pSrcCvtBytes );
+ sal_Size ImplUnicodeToChar( const ImplTextConverterData* pData, void* pContext,
+                             const sal_Unicode* pSrcBuf, sal_Size nSrcChars,
+                             sal_Char* pDestBuf, sal_Size nDestBytes,


More information about the ooo-build-commit mailing list