[Libreoffice-commits] .: 8 commits - oox/inc oox/source sc/inc sc/source sd/source svx/inc sw/inc sw/source unusedcode.easy

Cédric Bosdonnat cbosdo at kemper.freedesktop.org
Thu Mar 15 09:01:33 PDT 2012


 oox/inc/oox/helper/attributelist.hxx     |    6 
 oox/inc/oox/helper/containerhelper.hxx   |   16 
 oox/inc/oox/helper/graphichelper.hxx     |    2 
 oox/source/helper/attributelist.cxx      |   10 
 oox/source/helper/containerhelper.cxx    |   18 
 oox/source/helper/graphichelper.cxx      |    5 
 sc/inc/scerrors.hxx                      |    4 
 sc/source/filter/excel/expop2.cxx        |    7 
 sc/source/ui/app/scdll.cxx               |    2 
 sc/source/ui/src/scerrors.src            |    8 
 sd/source/filter/eppt/epptooxml.hxx      |    1 
 sd/source/filter/eppt/pptx-epptooxml.cxx |   10 
 svx/inc/svx/tbcontrl.hxx                 |    3 
 sw/inc/editsh.hxx                        |   19 
 sw/source/core/edit/edattr.cxx           |   59 -
 sw/source/core/text/itrform2.cxx         |  576 ++++++++++++++
 sw/source/core/text/itrform2.hxx         |   39 -
 sw/source/core/text/txtfly.cxx           | 1198 +++++--------------------------
 sw/source/core/text/txtfly.hxx           |  298 ++++++-
 sw/source/ui/inc/formatclipboard.hxx     |   30 
 unusedcode.easy                          |    5 
 21 files changed, 1167 insertions(+), 1149 deletions(-)

New commits:
commit a13a9a048a5c76e874073f6738a248286b5171fa
Author: Petr Vorel <petr.vorel at gmail.com>
Date:   Thu Mar 15 11:40:15 2012 +0100

    remove unused code (oox, sd)

diff --git a/oox/inc/oox/helper/attributelist.hxx b/oox/inc/oox/helper/attributelist.hxx
index d0a0600..c60c6f8 100644
--- a/oox/inc/oox/helper/attributelist.hxx
+++ b/oox/inc/oox/helper/attributelist.hxx
@@ -66,12 +66,6 @@ public:
 
     /** Returns the 32-bit signed integer value from the passed string (hexadecimal). */
     static sal_Int32    decodeIntegerHex( const ::rtl::OUString& rValue );
-
-    /** Returns the 32-bit unsigned integer value from the passed string (hexadecimal). */
-    static sal_uInt32   decodeUnsignedHex( const ::rtl::OUString& rValue );
-
-    /** Returns the 64-bit signed integer value from the passed string (hexadecimal). */
-    static sal_Int64    decodeHyperHex( const ::rtl::OUString& rValue );
 };
 
 // ============================================================================
diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx
index 5c9dc88..eef9429 100644
--- a/oox/inc/oox/helper/containerhelper.hxx
+++ b/oox/inc/oox/helper/containerhelper.hxx
@@ -173,22 +173,6 @@ public:
     static ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
                         createIndexContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );
 
-    /** Inserts an object into an indexed container.
-
-        @param rxIndexContainer  com.sun.star.container.XIndexContainer
-            interface of the indexed container.
-
-        @param nIndex  Insertion index for the object.
-
-        @param rObject  The object to be inserted.
-
-        @return  True = object successfully inserted.
-     */
-    static bool         insertByIndex(
-                            const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rxIndexContainer,
-                            sal_Int32 nIndex,
-                            const ::com::sun::star::uno::Any& rObject );
-
     // com.sun.star.container.XNameContainer ----------------------------------
 
     /** Creates a new name container object from scratch. */
diff --git a/oox/inc/oox/helper/graphichelper.hxx b/oox/inc/oox/helper/graphichelper.hxx
index d3507fa..9881200 100644
--- a/oox/inc/oox/helper/graphichelper.hxx
+++ b/oox/inc/oox/helper/graphichelper.hxx
@@ -93,8 +93,6 @@ public:
     sal_Int32           convertScreenPixelXToHmm( double fPixelX ) const;
     /** Converts the passed value from vertical screen pixels to 1/100 mm. */
     sal_Int32           convertScreenPixelYToHmm( double fPixelY ) const;
-    /** Converts the passed point from screen pixels to 1/100 mm. */
-    ::com::sun::star::awt::Point convertScreenPixelToHmm( const ::com::sun::star::awt::Point& rPixel ) const;
     /** Converts the passed size from screen pixels to 1/100 mm. */
     ::com::sun::star::awt::Size convertScreenPixelToHmm( const ::com::sun::star::awt::Size& rPixel ) const;
 
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
index 33f4ed5..f1d114d 100644
--- a/oox/source/helper/attributelist.cxx
+++ b/oox/source/helper/attributelist.cxx
@@ -122,16 +122,6 @@ sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue )
     return rValue.toInt32( 16 );
 }
 
-sal_uInt32 AttributeConversion::decodeUnsignedHex( const OUString& rValue )
-{
-    return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 );
-}
-
-sal_Int64 AttributeConversion::decodeHyperHex( const OUString& rValue )
-{
-    return rValue.toInt64( 16 );
-}
-
 // ============================================================================
 
 AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx
index 23bad22..a19e9b4 100644
--- a/oox/source/helper/containerhelper.cxx
+++ b/oox/source/helper/containerhelper.cxx
@@ -119,24 +119,6 @@ Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Refere
     return xContainer;
 }
 
-bool ContainerHelper::insertByIndex(
-        const Reference< XIndexContainer >& rxIndexContainer,
-        sal_Int32 nIndex, const Any& rObject )
-{
-    OSL_ENSURE( rxIndexContainer.is(), "ContainerHelper::insertByIndex - missing XIndexContainer interface" );
-    bool bRet = false;
-    try
-    {
-        rxIndexContainer->insertByIndex( nIndex, rObject );
-        bRet = true;
-    }
-    catch( Exception& )
-    {
-    }
-    OSL_ENSURE( bRet, "ContainerHelper::insertByIndex - cannot insert object" );
-    return bRet;
-}
-
 Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XComponentContext >& rxContext )
 {
     Reference< XNameContainer > xContainer;
diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
index ddca88f..66f6313 100644
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -185,11 +185,6 @@ sal_Int32 GraphicHelper::convertScreenPixelYToHmm( double fPixelY ) const
     return lclConvertScreenPixelToHmm( fPixelY, mfPixelPerHmmY );
 }
 
-awt::Point GraphicHelper::convertScreenPixelToHmm( const awt::Point& rPixel ) const
-{
-    return awt::Point( convertScreenPixelXToHmm( rPixel.X ), convertScreenPixelYToHmm( rPixel.Y ) );
-}
-
 awt::Size GraphicHelper::convertScreenPixelToHmm( const awt::Size& rPixel ) const
 {
     return awt::Size( convertScreenPixelXToHmm( rPixel.Width ), convertScreenPixelYToHmm( rPixel.Height ) );
diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx
index 8182ed9..0fb9801 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -125,7 +125,6 @@ protected:
     void WriteAnimationProperty( ::sax_fastparser::FSHelperPtr pFS, const ::com::sun::star::uno::Any& rAny );
     void WriteAnimationTarget( ::sax_fastparser::FSHelperPtr pFS, ::com::sun::star::uno::Any aTarget );
     bool WriteComments( sal_uInt32 nPageNum );
-    void WriteTextStyle( ::sax_fastparser::FSHelperPtr pFS, int nInstance, sal_Int32 xmlToken );
     void WriteTextStyleLevel( ::sax_fastparser::FSHelperPtr pFS, int nInstance, int nLevel );
     void ImplWriteBackground( ::sax_fastparser::FSHelperPtr pFS, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXBackgroundPropSet );
     void WriteTransition( ::sax_fastparser::FSHelperPtr pFS );
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index a826634..0ff53d5 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -1551,16 +1551,6 @@ void PowerPointExport::WriteTextStyleLevel( FSHelperPtr pFS, int nInstance, int
     pFS->endElementNS( XML_a, PowerPointExport::nStyleLevelToken[ nLevel ] );
 }
 
-void PowerPointExport::WriteTextStyle( FSHelperPtr pFS, int nInstance, sal_Int32 xmlToken )
-{
-    pFS->startElementNS( XML_p, xmlToken, FSEND );
-
-    for( int nLevel = 0; nLevel < 5; nLevel ++ )
-    WriteTextStyleLevel( pFS, nInstance, nLevel );
-
-    pFS->endElementNS( XML_p, xmlToken );
-}
-
 void PowerPointExport::ImplWriteSlideMaster( sal_uInt32 nPageNum, Reference< XPropertySet > aXBackgroundPropSet )
 {
     DBG(printf("write slide master: %" SAL_PRIuUINT32 "\n----------------\n", nPageNum));
diff --git a/unusedcode.easy b/unusedcode.easy
index 5e63e06..ac7a640 100755
--- a/unusedcode.easy
+++ b/unusedcode.easy
@@ -888,11 +888,6 @@ nullcanvas::SpriteCanvasHelper::scrollUpdate(basegfx::B2DRange const&, basegfx::
 o3tltests::cow_wrapper_client2::queryUnmodified() const
 o3tltests::cow_wrapper_client3::queryUnmodified() const
 ooo::vba::extractIntFromAny(com::sun::star::uno::Any const&)
-oox::AttributeConversion::decodeHyperHex(rtl::OUString const&)
-oox::AttributeConversion::decodeUnsignedHex(rtl::OUString const&)
-oox::ContainerHelper::insertByIndex(com::sun::star::uno::Reference<com::sun::star::container::XIndexContainer> const&, int, com::sun::star::uno::Any const&)
-oox::GraphicHelper::convertScreenPixelToHmm(com::sun::star::awt::Point const&) const
-oox::core::PowerPointExport::WriteTextStyle(boost::shared_ptr<sax_fastparser::FastSerializerHelper>, int, int)
 oox::drawingml::ChartExport::exportDataSeq(com::sun::star::uno::Reference<com::sun::star::chart2::data::XDataSequence> const&, int)
 oox::drawingml::ChartExport::exportXAxis(oox::drawingml::AxisIdPair)
 oox::drawingml::ChartExport::exportYAxis(oox::drawingml::AxisIdPair)
commit c8620de6dc24f79c1d290f1b94665edfbcf5c000
Author: Maxime de Roucy <mderoucy at linagora.com>
Date:   Wed Mar 14 15:39:31 2012 +0100

    Add comments in formatclipboard.hxx

diff --git a/sw/source/ui/inc/formatclipboard.hxx b/sw/source/ui/inc/formatclipboard.hxx
index 07891a0..4cca4e7 100644
--- a/sw/source/ui/inc/formatclipboard.hxx
+++ b/sw/source/ui/inc/formatclipboard.hxx
@@ -46,24 +46,54 @@ public:
     SwFormatClipboard();
     ~SwFormatClipboard();
 
+    /**
+     * Test if the object contains text or paragraph attribute
+     */
     bool HasContent() const;
     bool HasContentForThisType( int nSelectionType ) const;
     bool CanCopyThisType( int nSelectionType ) const;
 
+    /**
+     * Store/Backup the text and paragraph attribute of the current selection.
+     *
+     * @param bPersistentCopy
+     * input parameter - specify if the Paste function will erase the current object.
+     */
     void Copy( SwWrtShell& rWrtShell, SfxItemPool& rPool, bool bPersistentCopy=false );
+
+    /**
+     * Paste the stored text and paragraph attributes on the current selection and current paragraph.
+     *
+     * @param bNoCharacterFormats
+     * Do not paste the character formats.
+     *
+     * @param bNoParagraphFormats
+     * Do not paste the paragraph formats.
+     */
     void Paste( SwWrtShell& rWrtShell, SfxStyleSheetBasePool* pPool
         , bool bNoCharacterFormats=false, bool bNoParagraphFormats=false );
+
+    /**
+     * Clear the currently stored text and paragraph attributes.
+     */
     void Erase();
 
 private:
     int         m_nSelectionType;
+
+    /** automatic/named character and paragraph attribute set */
     SfxItemSet* m_pItemSet;
+
+    /** table attribute set */
     SfxItemSet* m_pTableItemSet;
 
+    /** name of the character format (if it exist) */
     String m_aCharStyle;
+    /** name of the paragraph format (if it exist) */
     String m_aParaStyle;
     //no frame style because it contains position information
 
+    /** specify if the Paste function have to clear the current object */
     bool   m_bPersistentCopy;
 };
 
commit cc8047941dc93d686568541391af56209df53f0a
Author: Maxime de Roucy <mderoucy at linagora.com>
Date:   Tue Mar 13 17:10:55 2012 +0100

    SwEditShell : use of the STL swap function

diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 02b61f1..a160b6e 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -44,6 +44,7 @@
 #include <tblenum.hxx>
 #include <IMark.hxx>
 
+#include <algorithm>
 #include <vector>
 #include <set>
 #include <swundo.hxx>
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 7f53689..b189c99 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -116,8 +116,8 @@ sal_Bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
 
         if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
         {
-            sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
-            nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
+            std::swap(nSttNd, nEndNd);
+            std::swap(nSttCnt, nEndCnt);
         }
 
         if( nEndNd - nSttNd >= getMaxLookup() )
@@ -195,11 +195,7 @@ SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
 
         // reverse start and end if they aren't sorted correctly
         if( nSttNd > nEndNd )
-        {
-            sal_uLong tmpNd = nSttNd;
-            nSttNd = nEndNd;
-            nEndNd = tmpNd;
-        }
+            std::swap(nSttNd, nEndNd);
 
         // for all the nodes in the current Point and Mark
         for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
@@ -343,9 +339,7 @@ sal_Bool SwEditShell::IsMoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) con
               nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
 
         if( nSttNd > nEndNd )
-        {
-            sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
-        }
+            std::swap(nSttNd, nEndNd);
 
         SwCntntNode* pCNd;
         for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
commit 5f679b3e8109cac5881d244a63bcdbc8fd21341d
Author: Maxime de Roucy <mderoucy at linagora.com>
Date:   Tue Mar 13 16:54:39 2012 +0100

    getMaxLookup in SwEditShell::GetPaMTxtFmtColl
    
    Handle getMaxLookup as the maximum number of node to inspect.

diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 35f80c6..7f53689 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -72,6 +72,7 @@ const sal_uInt16& getMaxLookup()
 sal_Bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
                               const bool bMergeIndentValuesOfNumRule ) const
 {
+    // ??? pPaM can be different from the Cursor ???
     if( GetCrsrCnt() > getMaxLookup() )
     {
         rSet.InvalidateAllItems();
@@ -182,8 +183,8 @@ SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl( ) const
 
 SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
 {
-    if ( GetCrsrCnt() > getMaxLookup() )
-        return NULL;
+    // number of nodes the function have explored so far
+    sal_uInt16 numberOfLookup = 0;
 
     SwPaM* pStartPaM = pPaM;
     do { // for all the point and mark (selections)
@@ -200,14 +201,18 @@ SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
             nEndNd = tmpNd;
         }
 
-        if( nEndNd - nSttNd >= getMaxLookup() )
-            break;
-
         // for all the nodes in the current Point and Mark
         for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
         {
             // get the node
             SwNode* pNd = GetDoc()->GetNodes()[ n ];
+
+            ++numberOfLookup;
+
+            // if the maximum number of node that can be inspected has been reached
+            if (numberOfLookup >= getMaxLookup())
+                return NULL;
+
             if( pNd->IsTxtNode() )
             {
                 // if it's a text node get its named character format
commit 685416523725d1971f39ad4b3971b7e22e7709a4
Author: Maxime de Roucy <mderoucy at linagora.com>
Date:   Tue Mar 13 16:20:59 2012 +0100

    rewrite and comment SwEditShell::GetPaMTxtFmtColl
    
    Classe SwEditShell.
    Add some doxygen description for GetCurTxtFmtColl and GetPaMTxtFmtColl.
    Rewrite of GetPaMTxtFmtColl in order to comment and simplify the code.

diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index f6ba735..02b61f1 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -295,7 +295,25 @@ public:
     SwTxtFmtColl& GetDfltTxtFmtColl() const;
     sal_uInt16 GetTxtFmtCollCount() const;
     SwTxtFmtColl& GetTxtFmtColl( sal_uInt16 nTxtFmtColl) const;
+    /**
+     * Get the named character format of the current selection.
+     *
+     * @see GetPaMTxtFmtColl()
+     *
+     * @return the named character format of the first node that contains one.
+     * Nodes are sort by order of appearance in the selections ;
+     * selections are sort by their order of creation
+     * (last created selection first, oldest selection at last).
+     */
     SwTxtFmtColl* GetCurTxtFmtColl() const;
+    /**
+     * Get the named character format of the selection(s) described by a SwPaM.
+     *
+     * @param pPaM
+     * input parameter - the selection where to look for the character format.
+     *
+     * @return the named character format of the first node that contains one.
+     */
     SwTxtFmtColl* GetPaMTxtFmtColl( SwPaM* pPaM ) const;
 
     // #i62675#
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 441ff2c..35f80c6 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -182,44 +182,46 @@ SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl( ) const
 
 SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
 {
-    SwTxtFmtColl *pFmt = 0;
-
     if ( GetCrsrCnt() > getMaxLookup() )
-        return 0;
+        return NULL;
 
     SwPaM* pStartPaM = pPaM;
-    do {
+    do { // for all the point and mark (selections)
+
+        // get the start and the end node of the current selection
         sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
               nEndNd = pPaM->GetPoint()->nNode.GetIndex();
-        xub_StrLen nSttCnt = pPaM->GetMark()->nContent.GetIndex(),
-                   nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
 
-        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        // reverse start and end if they aren't sorted correctly
+        if( nSttNd > nEndNd )
         {
-            sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
-            nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
+            sal_uLong tmpNd = nSttNd;
+            nSttNd = nEndNd;
+            nEndNd = tmpNd;
         }
 
         if( nEndNd - nSttNd >= getMaxLookup() )
-        {
-            pFmt = 0;
             break;
-        }
 
+        // for all the nodes in the current Point and Mark
         for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
         {
+            // get the node
             SwNode* pNd = GetDoc()->GetNodes()[ n ];
             if( pNd->IsTxtNode() )
             {
-                if( !pFmt )
-                    pFmt = ((SwTxtNode*)pNd)->GetTxtColl();
-                else if( pFmt == ((SwTxtNode*)pNd)->GetTxtColl() ) // ???
-                    break;
+                // if it's a text node get its named character format
+                SwTxtFmtColl* pFmt = static_cast<SwTxtNode*>(pNd)->GetTxtColl();
+
+                // if the character format exist stop here and return it
+                if( pFmt != NULL )
+                    return pFmt;
             }
         }
-    } while ( ( pPaM = ( SwPaM* )pPaM->GetNext() ) != pStartPaM );
+    } while ( ( pPaM = static_cast<SwPaM*>(pPaM->GetNext()) ) != pStartPaM );
 
-    return pFmt;
+    // if none of the selected node contain a named character format
+    return NULL;
 }
 
 
commit 88dd798c08158af747b143b3c4994a184224f13b
Author: Maxime de Roucy <mderoucy at linagora.com>
Date:   Thu Mar 8 14:49:58 2012 +0100

    add SCWARN_EXPORT_MAXTAB and SCWARN_EXPORT_MAXCOL
    
    Create separate warnings when the maximum number of row, columns or
    sheets is reach in the export filter to xls forma.

diff --git a/sc/inc/scerrors.hxx b/sc/inc/scerrors.hxx
index 735f7ba..fc6b9cb 100644
--- a/sc/inc/scerrors.hxx
+++ b/sc/inc/scerrors.hxx
@@ -68,7 +68,9 @@
 #define SCWARN_EXPORT_NONCONVERTIBLE_CHARS  (   1 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
 #define SCWARN_EXPORT_ASCII         (   2 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
 #define SCWARN_EXPORT_MAXROW        (   3 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
-#define SCWARN_EXPORT_DATALOST      (   4 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
+#define SCWARN_EXPORT_MAXCOL        (   4 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
+#define SCWARN_EXPORT_MAXTAB        (   5 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
+#define SCWARN_EXPORT_DATALOST      (   6 | ERRCODE_CLASS_EXPORT | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
 
 // ERRCODE_CLASS_GENERAL
 #define SCWARN_CORE_HARD_RECALC     (   1 | ERRCODE_CLASS_GENERAL | ERRCODE_WARNING_MASK | ERRCODE_AREA_SC )
diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx
index a8a4ce1..ab31d97 100644
--- a/sc/source/filter/excel/expop2.cxx
+++ b/sc/source/filter/excel/expop2.cxx
@@ -124,10 +124,13 @@ FltError ExportBiff5::Write()
             sfx2::SaveOlePropertySet(xDocProps, xRootStrg );
     }
 
-    //! TODO: separate warnings for columns and sheets
     const XclExpAddressConverter& rAddrConv = GetAddressConverter();
-    if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
+    if( rAddrConv.IsRowTruncated() )
         return SCWARN_EXPORT_MAXROW;
+    if( rAddrConv.IsColTruncated() )
+        return SCWARN_EXPORT_MAXCOL;
+    if( rAddrConv.IsTabTruncated() )
+        return SCWARN_EXPORT_MAXTAB;
 
     return eERR_OK;
 }
diff --git a/sc/source/ui/src/scerrors.src b/sc/source/ui/src/scerrors.src
index 2a2e2ad..f77dcf0 100644
--- a/sc/source/ui/src/scerrors.src
+++ b/sc/source/ui/src/scerrors.src
@@ -150,6 +150,14 @@ Resource RID_ERRHDLSC
     {
         Text [ en-US ] = "The document contains more rows than supported in the selected format.\nAdditional rows were not saved." ;
     };
+    String SCWARN_EXPORT_MAXCOL & ERRCODE_RES_MASK
+    {
+        Text [ en-US ] = "The document contains more columns than supported in the selected format.\nAdditional columns were not saved." ;
+    };
+    String SCWARN_EXPORT_MAXTAB & ERRCODE_RES_MASK
+    {
+        Text [ en-US ] = "The document contains more sheets than supported in the selected format.\nAdditional sheets were not saved." ;
+    };
     String SCWARN_IMPORT_INFOLOST & ERRCODE_RES_MASK
     {
         Text [ en-US ] = "The document contains information not recognized by this program version.\nResaving the document will delete this information!" ;
commit 2e7e5e79c025b75fc01e600cc924f34b4c8b22ce
Author: Winfried Donkers <osc at dci-electronics.nl>
Date:   Mon Mar 12 17:25:26 2012 +0100

    fdo#45671 split button for calc cell border color

diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
index ece5a1f..25712d4 100644
--- a/sc/source/ui/app/scdll.cxx
+++ b/sc/source/ui/app/scdll.cxx
@@ -207,7 +207,7 @@ void ScDLL::Init()
     SvxColorExtToolBoxControl       ::RegisterControl(SID_BACKGROUND_COLOR,     pMod);
     SvxFrameToolBoxControl          ::RegisterControl(SID_ATTR_BORDER,          pMod);
     SvxFrameLineStyleToolBoxControl ::RegisterControl(SID_FRAME_LINESTYLE,      pMod);
-    SvxFrameLineColorToolBoxControl ::RegisterControl(SID_FRAME_LINECOLOR,      pMod);
+    SvxColorExtToolBoxControl       ::RegisterControl(SID_FRAME_LINECOLOR,      pMod);
     SvxClipBoardControl             ::RegisterControl(SID_PASTE,                pMod );
     SvxUndoRedoControl              ::RegisterControl(SID_UNDO,                 pMod );
     SvxUndoRedoControl              ::RegisterControl(SID_REDO,                 pMod );
diff --git a/svx/inc/svx/tbcontrl.hxx b/svx/inc/svx/tbcontrl.hxx
index 8fb558e..7cc2479 100644
--- a/svx/inc/svx/tbcontrl.hxx
+++ b/svx/inc/svx/tbcontrl.hxx
@@ -87,6 +87,9 @@
         for  cell background color (calc)
         Execute-Id      SID_ATTR_CHAR_COLOR_BACKGROUND
 
+        for table/cell border color (writer, calc)
+        Execute-Id      SID_FRAME_LINECOLOR
+
         SvxColorToolBoxControl
         --------------------------------
         Item type:      SvxBrushItem
commit 32eed8ac666dc79b038ddc0b14769ae4d4f24587
Author: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>
Date:   Wed Mar 14 16:38:43 2012 +0100

    Cleanup in txtfly.cxx and translated comments to english there

diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index f9163af..a4233da 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -31,7 +31,10 @@
 
 #include <com/sun/star/i18n/ScriptType.hdl>
 #include <editeng/lspcitem.hxx>
+#include <txtflcnt.hxx>
 #include <txtftn.hxx>
+#include <flyfrms.hxx>
+#include <fmtflcnt.hxx>
 #include <fmtftn.hxx>
 #include <ftninfo.hxx>
 #include <charfmt.hxx>
@@ -2004,6 +2007,579 @@ sal_Bool SwTxtFormatter::AllowRepaintOpt() const
     return bOptimizeRepaint;
 }
 
+void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom )
+{
+    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
+            "SwTxtFormatter::CalcUnclipped with unswapped frame" );
+
+    long nFlyAsc, nFlyDesc;
+    pCurr->MaxAscentDescent( rTop, rBottom, nFlyAsc, nFlyDesc );
+    rTop = Y() + GetCurr()->GetAscent();
+    rBottom = rTop + nFlyDesc;
+    rTop -= nFlyAsc;
+}
+
+
+void SwTxtFormatter::UpdatePos( SwLineLayout *pCurrent, Point aStart,
+    xub_StrLen nStartIdx, sal_Bool bAllWays ) const
+{
+    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
+            "SwTxtFormatter::UpdatePos with unswapped frame" );
+
+    if( GetInfo().IsTest() )
+        return;
+    SwLinePortion *pFirst = pCurrent->GetFirstPortion();
+    SwLinePortion *pPos = pFirst;
+    SwTxtPaintInfo aTmpInf( GetInfo() );
+    aTmpInf.SetpSpaceAdd( pCurrent->GetpLLSpaceAdd() );
+    aTmpInf.ResetSpaceIdx();
+    aTmpInf.SetKanaComp( pCurrent->GetpKanaComp() );
+    aTmpInf.ResetKanaIdx();
+
+    // The frame's size
+    aTmpInf.SetIdx( nStartIdx );
+    aTmpInf.SetPos( aStart );
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+    pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
+
+    KSHORT nTmpHeight = pCurrent->GetRealHeight();
+    KSHORT nAscent = pCurrent->GetAscent() + nTmpHeight - pCurrent->Height();
+    objectpositioning::AsCharFlags nFlags = AS_CHAR_ULSPACE;
+    if( GetMulti() )
+    {
+        aTmpInf.SetDirection( GetMulti()->GetDirection() );
+        if( GetMulti()->HasRotation() )
+        {
+            nFlags |= AS_CHAR_ROTATE;
+            if( GetMulti()->IsRevers() )
+            {
+                nFlags |= AS_CHAR_REVERSE;
+                aTmpInf.X( aTmpInf.X() - nAscent );
+            }
+            else
+                aTmpInf.X( aTmpInf.X() + nAscent );
+        }
+        else
+        {
+            if ( GetMulti()->IsBidi() )
+                nFlags |= AS_CHAR_BIDI;
+            aTmpInf.Y( aTmpInf.Y() + nAscent );
+        }
+    }
+    else
+        aTmpInf.Y( aTmpInf.Y() + nAscent );
+
+    while( pPos )
+    {
+        // We only know one case where changing the position (caused by the
+        // adjustment) could be relevant for a portion: We need to SetRefPoint
+        // for FlyCntPortions.
+        if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
+            && ( bAllWays || !IsQuick() ) )
+        {
+            pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+
+            if( pPos->IsGrfNumPortion() )
+            {
+                if( !nFlyAsc && !nFlyDesc )
+                {
+                    nTmpAscent = nAscent;
+                    nFlyAsc = nAscent;
+                    nTmpDescent = nTmpHeight - nAscent;
+                    nFlyDesc = nTmpDescent;
+                }
+                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
+                                                   nFlyAsc, nFlyDesc );
+            }
+            else
+            {
+                Point aBase( aTmpInf.GetPos() );
+                if ( GetInfo().GetTxtFrm()->IsVertical() )
+                    GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aBase );
+
+                ((SwFlyCntPortion*)pPos)->SetBase( *aTmpInf.GetTxtFrm(),
+                    aBase, nTmpAscent, nTmpDescent, nFlyAsc,
+                    nFlyDesc, nFlags );
+            }
+        }
+        if( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasFlyInCntnt() )
+        {
+            OSL_ENSURE( !GetMulti(), "Too much multi" );
+            ((SwTxtFormatter*)this)->pMulti = (SwMultiPortion*)pPos;
+            SwLineLayout *pLay = &GetMulti()->GetRoot();
+            Point aSt( aTmpInf.X(), aStart.Y() );
+
+            if ( GetMulti()->HasBrackets() )
+            {
+                OSL_ENSURE( GetMulti()->IsDouble(), "Brackets only for doubles");
+                aSt.X() += ((SwDoubleLinePortion*)GetMulti())->PreWidth();
+            }
+            else if( GetMulti()->HasRotation() )
+            {
+                aSt.Y() += pCurrent->GetAscent() - GetMulti()->GetAscent();
+                if( GetMulti()->IsRevers() )
+                    aSt.X() += GetMulti()->Width();
+                else
+                    aSt.Y() += GetMulti()->Height();
+               }
+            else if ( GetMulti()->IsBidi() )
+                // jump to end of the bidi portion
+                aSt.X() += pLay->Width();
+
+            xub_StrLen nStIdx = aTmpInf.GetIdx();
+            do
+            {
+                UpdatePos( pLay, aSt, nStIdx, bAllWays );
+                nStIdx = nStIdx + pLay->GetLen();
+                aSt.Y() += pLay->Height();
+                pLay = pLay->GetNext();
+            } while ( pLay );
+            ((SwTxtFormatter*)this)->pMulti = NULL;
+        }
+        pPos->Move( aTmpInf );
+        pPos = pPos->GetPortion();
+    }
+}
+
+
+void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const
+{
+    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
+            "SwTxtFormatter::AlignFlyInCntBase with unswapped frame" );
+
+    if( GetInfo().IsTest() )
+        return;
+    SwLinePortion *pFirst = pCurr->GetFirstPortion();
+    SwLinePortion *pPos = pFirst;
+    objectpositioning::AsCharFlags nFlags = AS_CHAR_NOFLAG;
+    if( GetMulti() && GetMulti()->HasRotation() )
+    {
+        nFlags |= AS_CHAR_ROTATE;
+        if( GetMulti()->IsRevers() )
+            nFlags |= AS_CHAR_REVERSE;
+    }
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+
+    while( pPos )
+    {
+        if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
+        {
+            pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+
+            if( pPos->IsGrfNumPortion() )
+                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
+                                                   nFlyAsc, nFlyDesc );
+            else
+            {
+                Point aBase;
+                if ( GetInfo().GetTxtFrm()->IsVertical() )
+                {
+                    nBaseLine = GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( nBaseLine );
+                    aBase = Point( nBaseLine, ((SwFlyCntPortion*)pPos)->GetRefPoint().Y() );
+                }
+                else
+                    aBase = Point( ((SwFlyCntPortion*)pPos)->GetRefPoint().X(), nBaseLine );
+
+                ((SwFlyCntPortion*)pPos)->SetBase( *GetInfo().GetTxtFrm(), aBase, nTmpAscent, nTmpDescent,
+                    nFlyAsc, nFlyDesc, nFlags );
+            }
+        }
+        pPos = pPos->GetPortion();
+    }
+}
+
+
+sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const
+{
+    OSL_ENSURE( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" );
+    if( GetCurr() )
+    {
+        // First we check, whether a fly overlaps with the line.
+        // = GetLineHeight()
+        const long nHeight = GetCurr()->GetRealHeight();
+        SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
+
+        SwRect aLineVert( aLine );
+        if ( pFrm->IsVertical() )
+            pFrm->SwitchHorizontalToVertical( aLineVert );
+        SwRect aInter( rInf.GetTxtFly()->GetFrm( aLineVert ) );
+        if ( pFrm->IsVertical() )
+            pFrm->SwitchVerticalToHorizontal( aInter );
+
+        if( !aInter.HasArea() )
+            return sal_False;
+
+        // We now check every portion that could have lowered for overlapping
+        // with the fly.
+        const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
+        aLine.Pos().Y() = Y() + GetCurr()->GetRealHeight() - GetCurr()->Height();
+        aLine.Height( GetCurr()->Height() );
+
+        while( pPos )
+        {
+            aLine.Width( pPos->Width() );
+
+            aLineVert = aLine;
+            if ( pFrm->IsVertical() )
+                pFrm->SwitchHorizontalToVertical( aLineVert );
+            aInter = rInf.GetTxtFly()->GetFrm( aLineVert );
+            if ( pFrm->IsVertical() )
+                pFrm->SwitchVerticalToHorizontal( aInter );
+
+            // New flys from below?
+            if( !pPos->IsFlyPortion() )
+            {
+                if( aInter.IsOver( aLine ) )
+                {
+                    aInter._Intersection( aLine );
+                    if( aInter.HasArea() )
+                    {
+                        // To be evaluated during reformat of this line:
+                        // RealHeight including spacing
+                        rInf.SetLineHeight( KSHORT(nHeight) );
+                        // Height without extra spacing
+                        rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
+                        return sal_True;
+                    }
+                }
+            }
+            else
+            {
+                // The fly portion is not intersected by a fly anymore
+                if ( ! aInter.IsOver( aLine ) )
+                {
+                    rInf.SetLineHeight( KSHORT(nHeight) );
+                    rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
+                    return sal_True;
+                }
+                else
+                {
+                    aInter._Intersection( aLine );
+
+                    // No area means a fly has become invalid because of
+                    // lowering the line => reformat the line
+                    // we also have to reformat the line, if the fly size
+                    // differs from the intersection interval's size.
+                    if( ! aInter.HasArea() ||
+                        ((SwFlyPortion*)pPos)->GetFixWidth() != aInter.Width() )
+                    {
+                        rInf.SetLineHeight( KSHORT(nHeight) );
+                        rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
+                        return sal_True;
+                    }
+                }
+            }
+
+            aLine.Left( aLine.Left() + pPos->Width() );
+            pPos = pPos->GetPortion();
+        }
+    }
+    return sal_False;
+}
+
+void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf )
+{
+    if( GetMulti() || rInf.GetFly() )
+        return;
+
+    SwTxtFly *pTxtFly = rInf.GetTxtFly();
+    if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() )
+        return;
+
+    const SwLinePortion *pLast = rInf.GetLast();
+
+    long nAscent;
+    long nTop = Y();
+    long nHeight;
+
+    if( rInf.GetLineHeight() )
+    {
+        // Real line height has already been calculated, we only have to
+        // search for intersections in the lower part of the strip
+        nAscent = pCurr->GetAscent();
+        nHeight = rInf.GetLineNettoHeight();
+        nTop += rInf.GetLineHeight() - nHeight;
+    }
+    else
+    {
+        nAscent = pLast->GetAscent();
+        nHeight = pLast->Height();
+
+        // We make a first guess for the lines real height
+        if ( ! pCurr->GetRealHeight() )
+            CalcRealHeight();
+
+        if ( pCurr->GetRealHeight() > nHeight )
+            nTop += pCurr->GetRealHeight() - nHeight;
+        else
+            // Important for fixed space between lines
+            nHeight = pCurr->GetRealHeight();
+    }
+
+    const long nLeftMar = GetLeftMargin();
+    const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
+
+    SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X()
+                  + nLeftMar - nLeftMin , nHeight );
+
+    SwRect aLineVert( aLine );
+    if ( pFrm->IsRightToLeft() )
+        pFrm->SwitchLTRtoRTL( aLineVert );
+
+    if ( pFrm->IsVertical() )
+        pFrm->SwitchHorizontalToVertical( aLineVert );
+    SwRect aInter( pTxtFly->GetFrm( aLineVert ) );
+
+    if ( pFrm->IsRightToLeft() )
+        pFrm->SwitchRTLtoLTR( aInter );
+
+    if ( pFrm->IsVertical() )
+        pFrm->SwitchVerticalToHorizontal( aInter );
+
+    if( aInter.IsOver( aLine ) )
+    {
+        aLine.Left( rInf.X() + nLeftMar );
+        sal_Bool bForced = sal_False;
+        if( aInter.Left() <= nLeftMin )
+        {
+            SwTwips nFrmLeft = GetTxtFrm()->Frm().Left();
+            if( GetTxtFrm()->Prt().Left() < 0 )
+                nFrmLeft += GetTxtFrm()->Prt().Left();
+            if( aInter.Left() < nFrmLeft )
+                aInter.Left( nFrmLeft );
+
+            long nAddMar = 0;
+            if ( pFrm->IsRightToLeft() )
+            {
+                nAddMar = pFrm->Frm().Right() - Right();
+                if ( nAddMar < 0 )
+                    nAddMar = 0;
+            }
+            else
+                nAddMar = nLeftMar - nFrmLeft;
+
+            aInter.Width( aInter.Width() + nAddMar );
+            // For a negative first line indent, we set this flag to show
+            // that the indentation/margin has been moved.
+            // This needs to be respected by the DefaultTab at the zero position.
+            if( IsFirstTxtLine() && HasNegFirst() )
+                bForced = sal_True;
+        }
+        aInter.Intersection( aLine );
+        if( !aInter.HasArea() )
+            return;
+
+        const sal_Bool bFullLine =  aLine.Left()  == aInter.Left() &&
+                                aLine.Right() == aInter.Right();
+
+        // Although no text is left, we need to format another line,
+        // because also empty lines need to avoid a Fly with no wrapping.
+        if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() )
+        {
+            rInf.SetNewLine( sal_True );
+            // 8221: We know that for dummies, it holds ascent == height
+            pCurr->SetDummy(sal_True);
+        }
+
+        // aInter becomes frame-local
+        aInter.Pos().X() -= nLeftMar;
+        SwFlyPortion *pFly = new SwFlyPortion( aInter );
+        if( bForced )
+        {
+            pCurr->SetForcedLeftMargin( sal_True );
+            rInf.ForcedLeftMargin( (sal_uInt16)aInter.Width() );
+        }
+
+        if( bFullLine )
+        {
+            // 8110: In order to properly flow around Flys with different
+            // wrapping attributes, we need to increase by units of line height.
+            // The last avoiding line should be adjusted in height, so that
+            // we don't get a frame spacing effect.
+            // 8221: It is important that ascent == height, because the FlyPortion
+            // values are transferred to pCurr in CalcLine and IsDummy() relies
+            // on this behaviour.
+            // To my knowledge we only have two places where DummyLines can be
+            // created: here and in MakeFlyDummies.
+            // IsDummy() is evaluated in IsFirstTxtLine(), when moving lines
+            // and in relation with DropCaps.
+            pFly->Height( KSHORT(aInter.Height()) );
+
+            // nNextTop now contains the margin's bottom edge, which we avoid
+            // or the next margin's top edge, which we need to respect.
+            // That means we can comfortably grow up to this value; that's how
+            // we save a few empty lines.
+            long nNextTop = pTxtFly->GetNextTop();
+            if ( pFrm->IsVertical() )
+                nNextTop = pFrm->SwitchVerticalToHorizontal( nNextTop );
+            if( nNextTop > aInter.Bottom() )
+            {
+                SwTwips nH = nNextTop - aInter.Top();
+                if( nH < KSHRT_MAX )
+                    pFly->Height( KSHORT( nH ) );
+            }
+            if( nAscent < pFly->Height() )
+                pFly->SetAscent( KSHORT(nAscent) );
+            else
+                pFly->SetAscent( pFly->Height() );
+        }
+        else
+        {
+            if( rInf.GetIdx() == rInf.GetTxt().Len() )
+            {
+                // Don't use nHeight, or we have a huge descent
+                pFly->Height( pLast->Height() );
+                pFly->SetAscent( pLast->GetAscent() );
+            }
+            else
+            {
+                pFly->Height( KSHORT(aInter.Height()) );
+                if( nAscent < pFly->Height() )
+                    pFly->SetAscent( KSHORT(nAscent) );
+                else
+                    pFly->SetAscent( pFly->Height() );
+            }
+        }
+
+        rInf.SetFly( pFly );
+
+        if( pFly->Fix() < rInf.Width() )
+            rInf.Width( pFly->Fix() );
+
+        GETGRID( pFrm->FindPageFrm() )
+        if ( pGrid )
+        {
+            const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
+            const SwLayoutFrm* pBody = pPageFrm->FindBodyCont();
+
+            SWRECTFN( pPageFrm )
+
+            const long nGridOrigin = pBody ?
+                                    (pBody->*fnRect->fnGetPrtLeft)() :
+                                    (pPageFrm->*fnRect->fnGetPrtLeft)();
+
+            const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
+            const sal_uInt16 nGridWidth = GETGRIDWIDTH( pGrid, pDoc);   //For textgrid refactor
+
+            SwTwips nStartX = GetLeftMargin();
+            if ( bVert )
+            {
+                Point aPoint( nStartX, 0 );
+                pFrm->SwitchHorizontalToVertical( aPoint );
+                nStartX = aPoint.Y();
+            }
+
+            const SwTwips nOfst = nStartX - nGridOrigin;
+            const SwTwips nTmpWidth = rInf.Width() + nOfst;
+
+            const sal_uLong i = nTmpWidth / nGridWidth + 1;
+
+            const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst;
+            if ( nNewWidth > 0 )
+                rInf.Width( (sal_uInt16)nNewWidth );
+            else
+                rInf.Width( 0 );
+        }
+    }
+}
+
+
+SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
+                                                   SwTxtAttr *pHint ) const
+{
+    SwFlyCntPortion *pRet = 0;
+    const SwFrm *pFrame = (SwFrm*)pFrm;
+
+    SwFlyInCntFrm *pFly;
+    SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt();
+    if( RES_FLYFRMFMT == pFrmFmt->Which() )
+        pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame);
+    else
+        pFly = NULL;
+    // aBase is the document-global position, from which the new extra portion is placed
+    // aBase.X() = Offset in in the line after the current position
+    // aBase.Y() = LineIter.Y() + Ascent of the current position
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+    // OD 08.01.2004 #i11859# - use new method <SwLineLayout::MaxAscentDescent(..)>
+    //SwLinePortion *pPos = pCurr->GetFirstPortion();
+    //lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
+    pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
+
+    // If the ascent of the frame is larger than the ascent of the current position,
+    // we use this one when calculating the base, or the frame would be positioned
+    // too much to the top, sliding down after all causing a repaint in an area
+    // he actually never was in.
+    KSHORT nAscent = 0;
+
+    const bool bTxtFrmVertical = GetInfo().GetTxtFrm()->IsVertical();
+
+    const bool bUseFlyAscent = pFly && pFly->GetValidPosFlag() &&
+                               0 != ( bTxtFrmVertical ?
+                                      pFly->GetRefPoint().X() :
+                                      pFly->GetRefPoint().Y() );
+
+    if ( bUseFlyAscent )
+         nAscent = static_cast<sal_uInt16>( Abs( int( bTxtFrmVertical ?
+                                                  pFly->GetRelPos().X() :
+                                                  pFly->GetRelPos().Y() ) ) );
+
+    // Check if be prefer to use the ascent of the last portion:
+    if ( IsQuick() ||
+         !bUseFlyAscent ||
+         nAscent < rInf.GetLast()->GetAscent() )
+    {
+        nAscent = rInf.GetLast()->GetAscent();
+    }
+    else if( nAscent > nFlyAsc )
+        nFlyAsc = nAscent;
+
+    Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
+    objectpositioning::AsCharFlags nMode = IsQuick() ? AS_CHAR_QUICK : 0;
+    if( GetMulti() && GetMulti()->HasRotation() )
+    {
+        nMode |= AS_CHAR_ROTATE;
+        if( GetMulti()->IsRevers() )
+            nMode |= AS_CHAR_REVERSE;
+    }
+
+    Point aTmpBase( aBase );
+    if ( GetInfo().GetTxtFrm()->IsVertical() )
+        GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
+
+    if( pFly )
+    {
+        pRet = new SwFlyCntPortion( *GetInfo().GetTxtFrm(), pFly, aTmpBase,
+                                    nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
+        // We need to make sure that our font is set again in the OutputDevice
+        // It could be that the FlyInCnt was added anew and GetFlyFrm() would
+        // in turn cause, that it'd be created anew again.
+        // This one's frames get formatted right away, which change the font and
+        // we have a bug (3322).
+        rInf.SelectFont();
+        if( pRet->GetAscent() > nAscent )
+        {
+            aBase.Y() = Y() + pRet->GetAscent();
+            nMode |= AS_CHAR_ULSPACE;
+            if( !rInf.IsTest() )
+                aTmpBase = aBase;
+                if ( GetInfo().GetTxtFrm()->IsVertical() )
+                    GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
+
+                pRet->SetBase( *rInf.GetTxtFrm(), aTmpBase, nTmpAscent,
+                               nTmpDescent, nFlyAsc, nFlyDesc, nMode );
+        }
+    }
+    else
+    {
+        pRet = new SwFlyCntPortion( *rInf.GetTxtFrm(), (SwDrawContact*)pFrmFmt->FindContactObj(),
+           aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
+    }
+    return pRet;
+}
+
 namespace {
     /*************************************************************************
     *                      ::CalcOptRepaint()
diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx
index a838806..ac4c1e0 100644
--- a/sw/source/core/text/itrform2.hxx
+++ b/sw/source/core/text/itrform2.hxx
@@ -40,9 +40,6 @@ class SwExpandPortion;
 class SwMultiPortion;
 class SwFtnPortion;
 
-/*************************************************************************
- *                      class SwTxtFormatter
- *************************************************************************/
 
 class SwTxtFormatter : public SwTxtPainter
 {
@@ -69,6 +66,10 @@ class SwTxtFormatter : public SwTxtPainter
     SwExpandPortion *NewFldPortion( SwTxtFormatInfo &rInf,
                                     const SwTxtAttr *pHt ) const;
     SwFtnPortion *NewFtnPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt );
+
+    /**
+        Sets a new portion for an object anchored as character
+     */
     SwFlyCntPortion *NewFlyCntPortion( SwTxtFormatInfo &rInf,
                                        SwTxtAttr *pHt ) const;
     SwLinePortion *WhichFirstPortion( SwTxtFormatInfo &rInf );
@@ -77,9 +78,18 @@ class SwTxtFormatter : public SwTxtPainter
 
     // Das Herzstueck der Formatierung
     void BuildPortions( SwTxtFormatInfo &rInf );
+
     sal_Bool BuildMultiPortion( SwTxtFormatInfo &rInf, SwMultiPortion& rMulti );
 
-    // Berechnung des emulierten rechten Rands
+    /**
+        Calculation of the emulated right side.
+
+        Determines the next object, that reaches into the rest of the line and
+        constructs the appropriate FlyPortion.
+        SwTxtFly::GetFrm(const SwRect&, sal_Bool) will be needed for this.
+
+        The right edge can be shortened by flys
+     */
     void CalcFlyWidth( SwTxtFormatInfo &rInf );
 
     // wird von SwTxtFormatter wegen UpdatePos ueberladen
@@ -103,14 +113,29 @@ class SwTxtFormatter : public SwTxtPainter
     // wird von FormatLine gerufen.
     void FormatReset( SwTxtFormatInfo &rInf );
 
-    // durch das Adjustment aendert sich die Position der Portions
+    /**
+        The position of the portions changes with the adjustment.
+
+        This method updates the reference point of the anchored as character objects,
+        for example after adjustment change (right alignment, justified, etc.)
+        Mainly to correct the X position.
+     */
     void UpdatePos( SwLineLayout *pCurr, Point aStart, xub_StrLen nStartIdx,
             sal_Bool bAllWays = sal_False ) const;
 
-    // Setze alle FlyInCntFrms auf die uebergebene BaseLine
+    /**
+        Set all anchored as character objects to the passed BaseLine
+        (in Y direction).
+     */
     void AlignFlyInCntBase( long nBaseLine ) const;
 
-    // Unterlaufbedingungen bei Flys
+    /**
+        This is called after the real height of the line has been calculated
+        Therefore it is possible, that more flys from below intersect with the
+        line, or that flys from above do not intersect with the line anymore.
+        We check this and return true, meaning that the line has to be
+        formatted again.
+     */
     sal_Bool ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const;
 
     // Portion einfuegen.
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7336d13..ec6d09a 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -30,27 +30,21 @@
 #include <vcl/outdev.hxx>
 #include <vcl/virdev.hxx>
 
-#include "viewsh.hxx"
 #include "pagefrm.hxx"
 #include "rootfrm.hxx"
-#include "viewimp.hxx"      // SwViewImp
 #include "pam.hxx"          // SwPosition
 #include "swregion.hxx"     // SwRegionRects
-#include "dcontact.hxx"     // SwContact
 #include "dflyobj.hxx"      // SdrObject
 #include "flyfrm.hxx"       // SwFlyFrm
 #include "frmtool.hxx"      // ::DrawGraphic
-#include "porfld.hxx"       // SwGrfNumPortion
-#include "txtfrm.hxx"       // SwTxtFrm
-#include "itrform2.hxx"     // SwTxtFormatter
 #include "porfly.hxx"       // NewFlyCntPortion
 #include "porfld.hxx"       // SwGrfNumPortion
 #include "txtfly.hxx"       // SwTxtFly
 #include "txtpaint.hxx"     // SwSaveClip
 #include "txtatr.hxx"       // SwTxtFlyCnt
 #include "notxtfrm.hxx"
-#include "flyfrms.hxx"
 #include "fmtcnct.hxx"      // SwFmtChain
+#include "inftxt.hxx"
 #include <pormulti.hxx>     // SwMultiPortion
 #include <svx/obj3d.hxx>
 #include <editeng/txtrange.hxx>
@@ -58,10 +52,8 @@
 #include <editeng/ulspitem.hxx>
 // #i28701#
 #include <editeng/lspcitem.hxx>
-#include <txtflcnt.hxx>
 #include <fmtsrnd.hxx>
 #include <fmtanchr.hxx>
-#include <fmtflcnt.hxx>
 #include <frmfmt.hxx>
 #include <pagedesc.hxx> // SwPageDesc
 #include <tgrditem.hxx>
@@ -71,9 +63,9 @@
 #include <IDocumentLayoutAccess.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <svx/svdoedge.hxx>
-#include "doc.hxx"
 
 #ifdef DBG_UTIL
+#include "viewsh.hxx"
 #include "viewopt.hxx"  // SwViewOptions, only for testing (Test2)
 #include "doc.hxx"
 #endif
@@ -81,646 +73,287 @@
 
 using namespace ::com::sun::star;
 
-/*****************************************************************************
- * Description:
- * SwTxtFly's purpose is to be the universal interface between
- * formatting/text output and the possibly overlapping free-flying frames.
- * During formatting the formatter gets the information from SwTxtFly, whether
- * a certain area is present by the attributes of an overlapping frame.
- * Such areas are represented by dummy portions.
- * The whole text output and touch-up is, again, forwarded to a SwTxtFly.
- * This one decides, whether parts of the text need to be clipped and splits
- * the areas for e.g. a DrawRect.
- * Please note that all free-flying frames are located in a PtrArray, sorted
- * by TopLeft.
- * Internally we always use document-global values. The IN and OUT parameters
- * are, however, adjusted to the needs of the LineIter most of the time. That
- * is: they are converted to frame- and window-local coordinates.
- * If multiple frames with wrap attributes are located on the same line, we get
- * the following settings for the text flow:
- *
- *      L/R    P     L     R     N
- *       P   -P-P- -P-L  -P R- -P N
- *       L   -L P- -L L  -L R- -L N
- *       R    R-P-  R-L   R R-  R N
- *       N    N P-  N L   N R-  N N
- *
- * (P=parallel, L=left, R=right, N=no wrap)
- *
- * We can describe the behaviour as follows:
- * Every frame can push away text, with the restriction that it only has influence
- * until the next frame.
- *****************************************************************************/
-
-void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom )
-{
-    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
-            "SwTxtFormatter::CalcUnclipped with unswapped frame" );
-
-    long nFlyAsc, nFlyDesc;
-    pCurr->MaxAscentDescent( rTop, rBottom, nFlyAsc, nFlyDesc );
-    rTop = Y() + GetCurr()->GetAscent();
-    rBottom = rTop + nFlyDesc;
-    rTop -= nFlyAsc;
-}
-
-/*************************************************************************
- * SwTxtFormatter::UpdatePos()
- * Updates the reference points of the character anchored objects,
- * e.g. after adjusting right-aligned, justified etc.
- * (That's mainly to correct the x position)
- *************************************************************************/
-
-void SwTxtFormatter::UpdatePos( SwLineLayout *pCurrent, Point aStart,
-    xub_StrLen nStartIdx, sal_Bool bAllWays ) const
+namespace
 {
-    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
-            "SwTxtFormatter::UpdatePos with unswapped frame" );
-
-    if( GetInfo().IsTest() )
-        return;
-    SwLinePortion *pFirst = pCurrent->GetFirstPortion();
-    SwLinePortion *pPos = pFirst;
-    SwTxtPaintInfo aTmpInf( GetInfo() );
-    aTmpInf.SetpSpaceAdd( pCurrent->GetpLLSpaceAdd() );
-    aTmpInf.ResetSpaceIdx();
-    aTmpInf.SetKanaComp( pCurrent->GetpKanaComp() );
-    aTmpInf.ResetKanaIdx();
-
-    // The frame's size
-    aTmpInf.SetIdx( nStartIdx );
-    aTmpInf.SetPos( aStart );
-
-    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
-    pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
-
-    KSHORT nTmpHeight = pCurrent->GetRealHeight();
-    KSHORT nAscent = pCurrent->GetAscent() + nTmpHeight - pCurrent->Height();
-    objectpositioning::AsCharFlags nFlags = AS_CHAR_ULSPACE;
-    if( GetMulti() )
+    // #i68520#
+    struct AnchoredObjOrder
     {
-        aTmpInf.SetDirection( GetMulti()->GetDirection() );
-        if( GetMulti()->HasRotation() )
-        {
-            nFlags |= AS_CHAR_ROTATE;
-            if( GetMulti()->IsRevers() )
-            {
-                nFlags |= AS_CHAR_REVERSE;
-                aTmpInf.X( aTmpInf.X() - nAscent );
-            }
-            else
-                aTmpInf.X( aTmpInf.X() + nAscent );
-        }
-        else
-        {
-            if ( GetMulti()->IsBidi() )
-                nFlags |= AS_CHAR_BIDI;
-            aTmpInf.Y( aTmpInf.Y() + nAscent );
-        }
-    }
-    else
-        aTmpInf.Y( aTmpInf.Y() + nAscent );
+        sal_Bool mbR2L;
+        SwRectFn mfnRect;
 
-    while( pPos )
-    {
-        // We only know one case where changing the position (caused by the
-        // adjustment) could be relevant for a portion: We need to SetRefPoint
-        // for FlyCntPortions.
-        if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
-            && ( bAllWays || !IsQuick() ) )
-        {
-            pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+        AnchoredObjOrder( const sal_Bool bR2L,
+                           SwRectFn fnRect )
+            : mbR2L( bR2L ),
+              mfnRect( fnRect )
+        {}
 
-            if( pPos->IsGrfNumPortion() )
+        bool operator()( const SwAnchoredObject* pListedAnchoredObj,
+                         const SwAnchoredObject* pNewAnchoredObj )
+        {
+            const SwRect aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
+            const SwRect aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
+            if ( ( mbR2L &&
+                   ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
+                     (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
+                 ( !mbR2L &&
+                   ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
+                     (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
             {
-                if( !nFlyAsc && !nFlyDesc )
+                SwTwips nTopDiff =
+                    (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
+                                        (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
+                if ( nTopDiff == 0 &&
+                     ( ( mbR2L &&
+                         ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
+                           (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
+                       ( !mbR2L &&
+                         ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
+                           (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
                 {
-                    nTmpAscent = nAscent;
-                    nFlyAsc = nAscent;
-                    nTmpDescent = nTmpHeight - nAscent;
-                    nFlyDesc = nTmpDescent;
+                    return true;
+                }
+                else if ( nTopDiff > 0 )
+                {
+                    return true;
                 }
-                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
-                                                   nFlyAsc, nFlyDesc );
             }
-            else
+            else if ( ( mbR2L &&
+                        ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
+                          (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
+                      ( !mbR2L &&
+                        ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
+                          (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
             {
-                Point aBase( aTmpInf.GetPos() );
-                if ( GetInfo().GetTxtFrm()->IsVertical() )
-                    GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aBase );
-
-                ((SwFlyCntPortion*)pPos)->SetBase( *aTmpInf.GetTxtFrm(),
-                    aBase, nTmpAscent, nTmpDescent, nFlyAsc,
-                    nFlyDesc, nFlags );
+                return true;
             }
-        }
-        if( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasFlyInCntnt() )
-        {
-            OSL_ENSURE( !GetMulti(), "Too much multi" );
-            ((SwTxtFormatter*)this)->pMulti = (SwMultiPortion*)pPos;
-            SwLineLayout *pLay = &GetMulti()->GetRoot();
-            Point aSt( aTmpInf.X(), aStart.Y() );
 
-            if ( GetMulti()->HasBrackets() )
-            {
-                OSL_ENSURE( GetMulti()->IsDouble(), "Brackets only for doubles");
-                aSt.X() += ((SwDoubleLinePortion*)GetMulti())->PreWidth();
-            }
-            else if( GetMulti()->HasRotation() )
-            {
-                aSt.Y() += pCurrent->GetAscent() - GetMulti()->GetAscent();
-                if( GetMulti()->IsRevers() )
-                    aSt.X() += GetMulti()->Width();
-                else
-                    aSt.Y() += GetMulti()->Height();
-               }
-            else if ( GetMulti()->IsBidi() )
-                // jump to end of the bidi portion
-                aSt.X() += pLay->Width();
-
-            xub_StrLen nStIdx = aTmpInf.GetIdx();
-            do
-            {
-                UpdatePos( pLay, aSt, nStIdx, bAllWays );
-                nStIdx = nStIdx + pLay->GetLen();
-                aSt.Y() += pLay->Height();
-                pLay = pLay->GetNext();
-            } while ( pLay );
-            ((SwTxtFormatter*)this)->pMulti = NULL;
+            return false;
         }
-        pPos->Move( aTmpInf );
-        pPos = pPos->GetPortion();
-    }
+    };
 }
 
-/*************************************************************************
- * SwTxtFormatter::AlignFlyInCntBase()
- * If needed, re-adjusts the character anchored objects to the y axis.
- *************************************************************************/
-
-void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const
+SwContourCache::SwContourCache() :
+    nPntCnt( 0 ), nObjCnt( 0 )
 {
-    OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
-            "SwTxtFormatter::AlignFlyInCntBase with unswapped frame" );
-
-    if( GetInfo().IsTest() )
-        return;
-    SwLinePortion *pFirst = pCurr->GetFirstPortion();
-    SwLinePortion *pPos = pFirst;
-    objectpositioning::AsCharFlags nFlags = AS_CHAR_NOFLAG;
-    if( GetMulti() && GetMulti()->HasRotation() )
-    {
-        nFlags |= AS_CHAR_ROTATE;
-        if( GetMulti()->IsRevers() )
-            nFlags |= AS_CHAR_REVERSE;
-    }
+    memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
+    memset( pTextRanger, 0, sizeof(pTextRanger) );
+}
 
-    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+SwContourCache::~SwContourCache()
+{
+    for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
+        ;
+}
 
-    while( pPos )
-    {
-        if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
-        {
-            pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+void SwContourCache::ClrObject( MSHORT nPos )
+{
+    OSL_ENSURE( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
+    nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
+    delete pTextRanger[ nPos ];
+    --nObjCnt;
+    memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
+             ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
+    memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
+             ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
+}
 
-            if( pPos->IsGrfNumPortion() )
-                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
-                                                   nFlyAsc, nFlyDesc );
-            else
+void ClrContourCache( const SdrObject *pObj )
+{
+    if( pContourCache && pObj )
+        for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
+            if( pObj == pContourCache->GetObject( i ) )
             {
-                Point aBase;
-                if ( GetInfo().GetTxtFrm()->IsVertical() )
-                {
-                    nBaseLine = GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( nBaseLine );
-                    aBase = Point( nBaseLine, ((SwFlyCntPortion*)pPos)->GetRefPoint().Y() );
-                }
-                else
-                    aBase = Point( ((SwFlyCntPortion*)pPos)->GetRefPoint().X(), nBaseLine );
-
-                ((SwFlyCntPortion*)pPos)->SetBase( *GetInfo().GetTxtFrm(), aBase, nTmpAscent, nTmpDescent,
-                    nFlyAsc, nFlyDesc, nFlags );
+                pContourCache->ClrObject( i );
+                break;
             }
-        }
-        pPos = pPos->GetPortion();
-    }
 }
 
-/*************************************************************************
- * SwTxtFly::ChkFlyUnderflow()
- * This is called after the real height of the line has been calculated.
- * Therefore it is possible, that more flys from below intersect with the
- * line, or that flys from above do not intersect with the line anymore.
- * We check this and return true, meaning that the line has to be
- * formatted again.
- *************************************************************************/
-
-sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const
+void ClrContourCache()
 {
-    OSL_ENSURE( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" );
-    if( GetCurr() )
+    if( pContourCache )
     {
-        // First we check, whether a fly overlaps with the line.
-        // = GetLineHeight()
-        const long nHeight = GetCurr()->GetRealHeight();
-        SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
-
-        SwRect aLineVert( aLine );
-        if ( pFrm->IsVertical() )
-            pFrm->SwitchHorizontalToVertical( aLineVert );
-        SwRect aInter( rInf.GetTxtFly()->GetFrm( aLineVert ) );
-        if ( pFrm->IsVertical() )
-            pFrm->SwitchVerticalToHorizontal( aInter );
-
-        if( !aInter.HasArea() )
-            return sal_False;
-
-        // We now check every portion that could have lowered for overlapping
-        // with the fly.
-        const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
-        aLine.Pos().Y() = Y() + GetCurr()->GetRealHeight() - GetCurr()->Height();
-        aLine.Height( GetCurr()->Height() );
-
-        while( pPos )
-        {
-            aLine.Width( pPos->Width() );
-
-            aLineVert = aLine;
-            if ( pFrm->IsVertical() )
-                pFrm->SwitchHorizontalToVertical( aLineVert );
-            aInter = rInf.GetTxtFly()->GetFrm( aLineVert );
-            if ( pFrm->IsVertical() )
-                pFrm->SwitchVerticalToHorizontal( aInter );
-
-            // New flys from below?
-            if( !pPos->IsFlyPortion() )
-            {
-                if( aInter.IsOver( aLine ) )
-                {
-                    aInter._Intersection( aLine );
-                    if( aInter.HasArea() )
-                    {
-                        // To be evaluated during reformat of this line:
-                        // RealHeight including spacing
-                        rInf.SetLineHeight( KSHORT(nHeight) );
-                        // Height without extra spacing
-                        rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
-                        return sal_True;
-                    }
-                }
-            }
-            else
-            {
-                // The fly portion is not intersected by a fly anymore
-                if ( ! aInter.IsOver( aLine ) )
-                {
-                    rInf.SetLineHeight( KSHORT(nHeight) );
-                    rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
-                    return sal_True;
-                }
-                else
-                {
-                    aInter._Intersection( aLine );
-
-                    // No area means a fly has become invalid because of
-                    // lowering the line => reformat the line.
-                    // We also have to reformat the line, if the fly size
-                    // differs from the intersection interval's size.
-                    if( ! aInter.HasArea() ||
-                        ((SwFlyPortion*)pPos)->GetFixWidth() != aInter.Width() )
-                    {
-                        rInf.SetLineHeight( KSHORT(nHeight) );
-                        rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
-                        return sal_True;
-                    }
-                }
-            }
-
-            aLine.Left( aLine.Left() + pPos->Width() );
-            pPos = pPos->GetPortion();
-        }
+        for( MSHORT i = 0; i < pContourCache->GetCount();
+             delete pContourCache->pTextRanger[ i++ ] )
+             ;
+        pContourCache->nObjCnt = 0;
+        pContourCache->nPntCnt = 0;
     }
-    return sal_False;
 }
 
-/*************************************************************************
- * SwTxtFormatter::CalcFlyWidth()
- * Determines the next object, that reaches into the rest of the line and
- * constructs the appropriate FlyPortion.
- * We use SwTxtFly.GetFrm(..) for that.
- *************************************************************************/
-
-// The right margin can be shortened by Flys.
-
-void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf )
+// #i68520#
+const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
+                                            const SwRect &rLine,
+                                            const SwTxtFrm* pFrm,
+                                            const long nXPos,
+                                            const sal_Bool bRight )
 {
-    if( GetMulti() || rInf.GetFly() )
-        return;
-
-    SwTxtFly *pTxtFly = rInf.GetTxtFly();
-    if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() )
-        return;
-
-    const SwLinePortion *pLast = rInf.GetLast();
-
-    long nAscent;
-    long nTop = Y();
-    long nHeight;
-
-    if( rInf.GetLineHeight() )
+    SwRect aRet;
+    const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
+    if( pFmt->GetSurround().IsContour() &&
+        ( !pAnchoredObj->ISA(SwFlyFrm) ||
+          ( static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower() &&
+            static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower()->IsNoTxtFrm() ) ) )
     {
-        // Real line height has already been calculated, we only have to
-        // search for intersections in the lower part of the strip
-        nAscent = pCurr->GetAscent();
-        nHeight = rInf.GetLineNettoHeight();
-        nTop += rInf.GetLineHeight() - nHeight;
+        aRet = pAnchoredObj->GetObjRectWithSpaces();
+        if( aRet.IsOver( rLine ) )
+        {
+            if( !pContourCache )
+                pContourCache = new SwContourCache;
+
+            aRet = pContourCache->ContourRect(
+                    pFmt, pAnchoredObj->GetDrawObj(), pFrm, rLine, nXPos, bRight );
+        }
+        else
+            aRet.Width( 0 );
     }
     else
     {
-        nAscent = pLast->GetAscent();
-        nHeight = pLast->Height();
-
-        // We make a first guess for the line's real height
-        if ( ! pCurr->GetRealHeight() )
-            CalcRealHeight();
-
-        if ( pCurr->GetRealHeight() > nHeight )
-            nTop += pCurr->GetRealHeight() - nHeight;
-        else
-            // Important for fixed space between lines
-            nHeight = pCurr->GetRealHeight();
+        aRet = pAnchoredObj->GetObjRectWithSpaces();
     }
 
-    const long nLeftMar = GetLeftMargin();
-    const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
-
-    SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X()
-                  + nLeftMar - nLeftMin , nHeight );
-
-    SwRect aLineVert( aLine );
-    if ( pFrm->IsRightToLeft() )
-        pFrm->SwitchLTRtoRTL( aLineVert );
-
-    if ( pFrm->IsVertical() )
-        pFrm->SwitchHorizontalToVertical( aLineVert );
-    SwRect aInter( pTxtFly->GetFrm( aLineVert ) );
-
-    if ( pFrm->IsRightToLeft() )
-        pFrm->SwitchRTLtoLTR( aInter );
-
-    if ( pFrm->IsVertical() )
-        pFrm->SwitchVerticalToHorizontal( aInter );
+    return aRet;
+}
 
-    if( aInter.IsOver( aLine ) )
+const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
+    const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine,
+    const long nXPos, const sal_Bool bRight )
+{
+    SwRect aRet;
+    MSHORT nPos = 0; // Suche im Cache ...
+    while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
+        ++nPos;
+    if( GetCount() == nPos ) // nicht gefunden
     {
-        aLine.Left( rInf.X() + nLeftMar );
-        sal_Bool bForced = sal_False;
-        if( aInter.Left() <= nLeftMin )
-        {
-            SwTwips nFrmLeft = GetTxtFrm()->Frm().Left();
-            if( GetTxtFrm()->Prt().Left() < 0 )
-                nFrmLeft += GetTxtFrm()->Prt().Left();
-            if( aInter.Left() < nFrmLeft )
-                aInter.Left( nFrmLeft );
-
-            long nAddMar = 0;
-            if ( pFrm->IsRightToLeft() )
-            {
-                nAddMar = pFrm->Frm().Right() - Right();
-                if ( nAddMar < 0 )
-                    nAddMar = 0;
-            }
-            else
-                nAddMar = nLeftMar - nFrmLeft;
-
-            aInter.Width( aInter.Width() + nAddMar );
-            // For a negative first line indent, we set this flag to show
-            // that the indentation/margin has been moved.
-            // This needs to be respected by the DefaultTab at the zero position.
-            if( IsFirstTxtLine() && HasNegFirst() )
-                bForced = sal_True;
-        }
-        aInter.Intersection( aLine );
-        if( !aInter.HasArea() )
-            return;
-
-        const sal_Bool bFullLine =  aLine.Left()  == aInter.Left() &&
-                                aLine.Right() == aInter.Right();
-
-        // Although no text is left, we need to format another line,
-        // because also empty lines need to avoid a Fly with no wrapping.
-        if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() )
+        if( nObjCnt == POLY_CNT )
         {
-            rInf.SetNewLine( sal_True );
-            // 8221: We know that for dummies, it holds ascent == height
-            pCurr->SetDummy(sal_True);
+            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+            delete pTextRanger[ nObjCnt ];
         }
+        ::basegfx::B2DPolyPolygon aPolyPolygon;
+        ::basegfx::B2DPolyPolygon* pPolyPolygon = 0L;
 
-        // aInter becomes frame-local
-        aInter.Pos().X() -= nLeftMar;
-        SwFlyPortion *pFly = new SwFlyPortion( aInter );
-        if( bForced )
+        if ( pObj->ISA(SwVirtFlyDrawObj) )
         {
-            pCurr->SetForcedLeftMargin( sal_True );
-            rInf.ForcedLeftMargin( (sal_uInt16)aInter.Width() );
+            // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik,
+            // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein
+            // ClrObject() auf.
+            PolyPolygon aPoly;
+            if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
+                aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
+                                     GetFlyFrm()->Frm().SVRect() );
+            aPolyPolygon.clear();
+            aPolyPolygon.append(aPoly.getB2DPolyPolygon());
         }
-
-        if( bFullLine )
+        else
         {
-            // 8110: In order to properly flow around Flys with different
-            // wrapping attributes, we need to increase by units of line height.
-            // The last avoiding line should be adjusted in height, so that
-            // we don't get a frame spacing effect.
-            // 8221: It is important that ascent == height, because the FlyPortion
-            // values are transferred to pCurr in CalcLine and IsDummy() relies
-            // on this behaviour.
-            // To my knowledge we only have two places where DummyLines can be
-            // created: here and in MakeFlyDummies.
-            // IsDummy() is evaluated in IsFirstTxtLine(), when moving lines
-            // and in relation with DropCaps.
-            pFly->Height( KSHORT(aInter.Height()) );
-
-            // nNextTop now contains the margin's bottom edge, which we avoid
-            // or the next margin's top edge, which we need to respect.
-            // That means we can comfortably grow up to this value; that's how
-            // we save a few empty lines.
-            long nNextTop = pTxtFly->GetNextTop();
-            if ( pFrm->IsVertical() )
-                nNextTop = pFrm->SwitchVerticalToHorizontal( nNextTop );
-            if( nNextTop > aInter.Bottom() )
+            if( !pObj->ISA( E3dObject ) )
             {
-                SwTwips nH = nNextTop - aInter.Top();
-                if( nH < KSHRT_MAX )
-                    pFly->Height( KSHORT( nH ) );
+                aPolyPolygon = pObj->TakeXorPoly();
             }
-            if( nAscent < pFly->Height() )
-                pFly->SetAscent( KSHORT(nAscent) );
-            else
-                pFly->SetAscent( pFly->Height() );
+
+            ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
+            pPolyPolygon = new ::basegfx::B2DPolyPolygon(aContourPoly);
         }
-        else
+        const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+        const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+        memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
+        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
+        pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem
+                             // GetContour() eingetragen werden.
+        pTextRanger[ 0 ] = new TextRanger( aPolyPolygon, pPolyPolygon, 20,
+            (sal_uInt16)rLRSpace.GetLeft(), (sal_uInt16)rLRSpace.GetRight(),
+            pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() );
+        pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
+        pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
+
+        delete pPolyPolygon;
+        // UPPER_LOWER_TEST
+#ifdef DBG_UTIL
+        const ViewShell* pTmpViewShell = pFmt->GetDoc()->GetCurrentViewShell();
+        if( pTmpViewShell )
         {
-            if( rInf.GetIdx() == rInf.GetTxt().Len() )
-            {
-                // Don't use nHeight, or we have a huge descent
-                pFly->Height( pLast->Height() );
-                pFly->SetAscent( pLast->GetAscent() );
-            }
-            else
+            sal_Bool bT2 = pTmpViewShell->GetViewOptions()->IsTest2();
+            sal_Bool bT6 = pTmpViewShell->GetViewOptions()->IsTest6();
+            if( bT2 || bT6 )
             {
-                pFly->Height( KSHORT(aInter.Height()) );
-                if( nAscent < pFly->Height() )
-                    pFly->SetAscent( KSHORT(nAscent) );
+                if( bT2 )
+                    pTextRanger[ 0 ]->SetFlag7( sal_True );
                 else
-                    pFly->SetAscent( pFly->Height() );
+                    pTextRanger[ 0 ]->SetFlag6( sal_True );
             }
         }
-
-        rInf.SetFly( pFly );
-
-        if( pFly->Fix() < rInf.Width() )
-            rInf.Width( pFly->Fix() );
-
-        GETGRID( pFrm->FindPageFrm() )
-        if ( pGrid )
+#endif
+        nPntCnt += pTextRanger[ 0 ]->GetPointCount();
+        while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
         {
-            const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
-            const SwLayoutFrm* pBody = pPageFrm->FindBodyCont();
-
-            SWRECTFN( pPageFrm )
-
-            const long nGridOrigin = pBody ?
-                                    (pBody->*fnRect->fnGetPrtLeft)() :
-                                    (pPageFrm->*fnRect->fnGetPrtLeft)();
-
-            const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
-            const sal_uInt16 nGridWidth = GETGRIDWIDTH( pGrid, pDoc); // For textgrid refactor
-
-            SwTwips nStartX = GetLeftMargin();
-            if ( bVert )
-            {
-                Point aPoint( nStartX, 0 );
-                pFrm->SwitchHorizontalToVertical( aPoint );
-                nStartX = aPoint.Y();
-            }
-
-            const SwTwips nOfst = nStartX - nGridOrigin;
-            const SwTwips nTmpWidth = rInf.Width() + nOfst;
-
-            const sal_uLong i = nTmpWidth / nGridWidth + 1;
-
-            const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst;
-            if ( nNewWidth > 0 )
-                rInf.Width( (sal_uInt16)nNewWidth );
-            else
-                rInf.Width( 0 );
+            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+            delete pTextRanger[ nObjCnt ];
         }
     }
-}
-
-/*****************************************************************************
- * SwTxtFormatter::NewFlyCntPortion
- * Creates a new portion for a character anchored object.
- *****************************************************************************/
-
-SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
-                                                   SwTxtAttr *pHint ) const
-{
-    SwFlyCntPortion *pRet = 0;
-    const SwFrm *pFrame = (SwFrm*)pFrm;
-
-    SwFlyInCntFrm *pFly;
-    SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt();
-    if( RES_FLYFRMFMT == pFrmFmt->Which() )
-        pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame);
-    else
-        pFly = NULL;
-    // aBase is the document-global position, from which the new extra portion is placed
-    // aBase.X() = Offset in in the line after the current position
-    // aBase.Y() = LineIter.Y() + Ascent of the current position
-
-    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
-    // OD 08.01.2004 #i11859# - use new method <SwLineLayout::MaxAscentDescent(..)>
-    //SwLinePortion *pPos = pCurr->GetFirstPortion();
-    //lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
-    pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
-
-    // If the ascent of the frame is larger than the ascent of the current position,
-    // we use this one when calculating the base, or the frame would be positioned
-    // too much to the top, sliding down after all causing a repaint in an area
-    // he actually never was in.
-    KSHORT nAscent = 0;
-
-    const bool bTxtFrmVertical = GetInfo().GetTxtFrm()->IsVertical();
-
-    const bool bUseFlyAscent = pFly && pFly->GetValidPosFlag() &&
-                               0 != ( bTxtFrmVertical ?
-                                      pFly->GetRefPoint().X() :
-                                      pFly->GetRefPoint().Y() );
-
-    if ( bUseFlyAscent )
-         nAscent = static_cast<sal_uInt16>( Abs( int( bTxtFrmVertical ?
-                                                  pFly->GetRelPos().X() :
-                                                  pFly->GetRelPos().Y() ) ) );
-
-    // Check if we prefer to use the ascent of the last portion:
-    if ( IsQuick() ||
-         !bUseFlyAscent ||
-         nAscent < rInf.GetLast()->GetAscent() )
+    else if( nPos )
     {
-        nAscent = rInf.GetLast()->GetAscent();
+        const SdrObject* pTmpObj = pSdrObj[ nPos ];
+        TextRanger* pTmpRanger = pTextRanger[ nPos ];
+        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
+        memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
+        pSdrObj[ 0 ] = pTmpObj;
+        pTextRanger[ 0 ] = pTmpRanger;
     }
-    else if( nAscent > nFlyAsc )
-        nFlyAsc = nAscent;
+    SWRECTFN( pFrm )
+    long nTmpTop = (rLine.*fnRect->fnGetTop)();
+    // fnGetBottom is top + height
+    long nTmpBottom = (rLine.*fnRect->fnGetBottom)();
 
-    Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
-    objectpositioning::AsCharFlags nMode = IsQuick() ? AS_CHAR_QUICK : 0;
-    if( GetMulti() && GetMulti()->HasRotation() )
-    {
-        nMode |= AS_CHAR_ROTATE;
-        if( GetMulti()->IsRevers() )
-            nMode |= AS_CHAR_REVERSE;
-    }
+    Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) );
 
-    Point aTmpBase( aBase );
-    if ( GetInfo().GetTxtFrm()->IsVertical() )
-        GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
+    LongDqPtr pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
 
-    if( pFly )
+    MSHORT nCount;
+    if( 0 != ( nCount = pTmp->size() ) )
     {
-        pRet = new SwFlyCntPortion( *GetInfo().GetTxtFrm(), pFly, aTmpBase,
-                                    nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
-        // We need to make sure that our font is set again in the OutputDevice
-        // It could be that the FlyInCnt was added anew and GetFlyFrm() would
-        // in turn cause, that it'd be created anew again.
-        // This one's frames get formatted right away, which change the font and
-        // we have a bug (3322).
-        rInf.SelectFont();
-        if( pRet->GetAscent() > nAscent )
+        MSHORT nIdx = 0;
+        while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
+            ++nIdx;
+        sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
+        sal_Bool bSet = sal_True;
+        if( bOdd )
+            --nIdx; // innerhalb eines Intervalls
+        else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
         {
-            aBase.Y() = Y() + pRet->GetAscent();
-            nMode |= AS_CHAR_ULSPACE;
-            if( !rInf.IsTest() )
-                aTmpBase = aBase;
-                if ( GetInfo().GetTxtFrm()->IsVertical() )
-                    GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
-
-                pRet->SetBase( *rInf.GetTxtFrm(), aTmpBase, nTmpAscent,
-                               nTmpDescent, nFlyAsc, nFlyDesc, nMode );
+            if( nIdx )
+                nIdx -= 2; // ein Intervall nach links gehen
+            else
+                bSet = sal_False; // vor dem erstem Intervall
+        }
+
+        if( bSet && nIdx < nCount )
+        {
+            (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(),
+                                               (rLine.*fnRect->fnGetHeight)() );
+            (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] );
+            (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 );
         }
     }
-    else
-    {
-        pRet = new SwFlyCntPortion( *rInf.GetTxtFrm(), (SwDrawContact*)pFrmFmt->FindContactObj(),
-           aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
-    }
-    return pRet;
+    return aRet;
 }
 
 
+SwTxtFly::SwTxtFly() :
+    pPage(0),
+    mpCurrAnchoredObj(0),
+    pCurrFrm(0),
+    pMaster(0),
+    mpAnchoredObjList(0),
+    nMinBottom(0),
+    nNextTop(0),
+    nIndex(0)
+{
+}
 
-/*************************************************************************
- * SwTxtFly::SwTxtFly()
- *************************************************************************/
+SwTxtFly::SwTxtFly( const SwTxtFrm *pFrm )
+{
+    CtorInitTxtFly( pFrm );
+}
 
 SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
 {
@@ -748,6 +381,11 @@ SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
     mbIgnoreObjsInHeaderFooter = rTxtFly.mbIgnoreObjsInHeaderFooter;
 }
 
+SwTxtFly::~SwTxtFly()
+{
+    delete mpAnchoredObjList;
+}
+
 void SwTxtFly::CtorInitTxtFly( const SwTxtFrm *pFrm )
 {
     mbIgnoreCurrentFrame = sal_False;
@@ -774,16 +412,6 @@ void SwTxtFly::CtorInitTxtFly( const SwTxtFrm *pFrm )
     nIndex = ULONG_MAX;
 }
 
-/*************************************************************************
- * SwTxtFly::_GetFrm()
- *
- * IN:  document-global (rRect)
- * OUT: frame-local (return value)
- *
- * This method is called during formatting of LineIter in order to:
- * 1. prepare the next FlyPortion
- * 2. remember new overlappings after changes to the line height
- *************************************************************************/
 
 SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
 {
@@ -804,15 +432,6 @@ SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
     return aRet;
 }
 
-/*************************************************************************
- * SwTxtFly::IsAnyFrm()
- *
- * IN: document-global
- * for the print area of the current frame
- *
- * Is used to disable the SwTxtFly if no objects overlap (relax)
- *
- *************************************************************************/
 
 sal_Bool SwTxtFly::IsAnyFrm() const
 {
@@ -827,16 +446,6 @@ sal_Bool SwTxtFly::IsAnyFrm() const
     return bRet;
 }
 
-/*************************************************************************
- * SwTxtFly::IsAnyObj()
- *
- * IN: document-global
- * OUT: sal_True     If a frame or DrawObj needs to be respected
- *
- * Only if this method returns sal_False, we can use optimizations like
- * Paint/FormatEmpty for empty paragraphs and also the virtual OutputDevice.
- *************************************************************************/
-
 sal_Bool SwTxtFly::IsAnyObj( const SwRect &rRect ) const
 {
    OSL_ENSURE( bOn, "SwTxtFly::IsAnyObj: Who's knocking?" );
@@ -876,17 +485,6 @@ const SwCntntFrm* SwTxtFly::_GetMaster()
     return pMaster;
 }
 
-/*************************************************************************
- * SwTxtFly::DrawTextOpaque()
- *
- * IN: document-global
- *
- * DrawTextOpaque() is called by DrawText().
- * The ClipRegions are placed int a way, that only those parts are displayed
- * which are not within the areas of FlyFrms which are opaque and above the
- * current Frame.
- * DrawText() takes over the on optimization!
- *************************************************************************/
 
 sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
 {
@@ -1011,14 +609,6 @@ sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
     return sal_True;
 }
 
-/*************************************************************************
- * SwTxtFly::DrawFlyRect()
- *
- * IN: window-local
- * We need to keep two subtelties in mind:
- * 1) DrawRect() above the ClipRect are allowed!
- * 2) FlyToRect() returns larger values than the frame data!
- *************************************************************************/
 
 void SwTxtFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect,
         const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic )
@@ -1284,61 +874,6 @@ sal_Bool SwTxtFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
     }
     return sal_False;
 }
-// #i68520#
-struct AnchoredObjOrder
-{
-    sal_Bool mbR2L;
-    SwRectFn mfnRect;
-
-    AnchoredObjOrder( const sal_Bool bR2L,
-                       SwRectFn fnRect )
-        : mbR2L( bR2L ),
-          mfnRect( fnRect )
-    {}
-
-    bool operator()( const SwAnchoredObject* pListedAnchoredObj,
-                     const SwAnchoredObject* pNewAnchoredObj )
-    {
-        const SwRect aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
-        const SwRect aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
-        if ( ( mbR2L &&
-               ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
-                 (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
-             ( !mbR2L &&
-               ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
-                 (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
-        {
-            SwTwips nTopDiff =
-                (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
-                                    (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
-            if ( nTopDiff == 0 &&
-                 ( ( mbR2L &&
-                     ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
-                       (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
-                   ( !mbR2L &&
-                     ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
-                       (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
-            {
-                return true;
-            }
-            else if ( nTopDiff > 0 )
-            {
-                return true;
-            }
-        }
-        else if ( ( mbR2L &&
-                    ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
-                      (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
-                  ( !mbR2L &&
-                    ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
-                      (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
-        {
-            return true;
-        }
-
-        return false;
-    }
-};
 
 // #i68520#
 SwAnchoredObjList* SwTxtFly::InitAnchoredObjList()
@@ -1503,234 +1038,6 @@ SwTwips SwTxtFly::CalcMinBottom() const
     return nRet;
 }
 
-/*************************************************************************
- * Hier erfolgt die Berechnung der Kontur ...
- * CalcBoundRect(..) und andere
- *************************************************************************/
-
-/*************************************************************************
- * class SwContourCache
- *************************************************************************/
-
-SwContourCache::SwContourCache() :
-    nPntCnt( 0 ), nObjCnt( 0 )
-{
-    memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
-    memset( pTextRanger, 0, sizeof(pTextRanger) );
-}
-
-SwContourCache::~SwContourCache()
-{
-    for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
-        ;
-}
-
-void SwContourCache::ClrObject( MSHORT nPos )
-{
-    OSL_ENSURE( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
-    nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
-    delete pTextRanger[ nPos ];
-    --nObjCnt;
-    memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
-             ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
-    memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
-             ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
-}
-
-void ClrContourCache( const SdrObject *pObj )
-{
-    if( pContourCache && pObj )
-        for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
-            if( pObj == pContourCache->GetObject( i ) )
-            {
-                pContourCache->ClrObject( i );
-                break;
-            }
-}
-
-void ClrContourCache()
-{
-    if( pContourCache )
-    {
-        for( MSHORT i = 0; i < pContourCache->GetCount();
-             delete pContourCache->pTextRanger[ i++ ] )
-             ;
-        pContourCache->nObjCnt = 0;
-        pContourCache->nPntCnt = 0;
-    }
-}
-
-/*************************************************************************
- * SwContourCache::CalcBoundRect
- * berechnet das Rechteck, welches vom Objekt in der angegebenen Zeile
- * ueberdeckt wird.
- * Bei _nicht_ konturumflossenen Objekten ist dies einfach die Ueber-
- * lappung von BoundRect (inkl. Abstand!) und Zeile,
- * bei Konturumfluss wird das Polypolygon des Objekts abgeklappert
- *************************************************************************/
-// #i68520#
-const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
-                                            const SwRect &rLine,
-                                            const SwTxtFrm* pFrm,
-                                            const long nXPos,
-                                            const sal_Bool bRight )
-{
-    SwRect aRet;
-    const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
-    if( pFmt->GetSurround().IsContour() &&
-        ( !pAnchoredObj->ISA(SwFlyFrm) ||
-          ( static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower() &&
-            static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower()->IsNoTxtFrm() ) ) )
-    {
-        aRet = pAnchoredObj->GetObjRectWithSpaces();
-        if( aRet.IsOver( rLine ) )
-        {
-            if( !pContourCache )
-                pContourCache = new SwContourCache;
-
-            aRet = pContourCache->ContourRect(
-                    pFmt, pAnchoredObj->GetDrawObj(), pFrm, rLine, nXPos, bRight );
-        }
-        else
-            aRet.Width( 0 );
-    }
-    else
-    {
-        aRet = pAnchoredObj->GetObjRectWithSpaces();
-    }
-
-    return aRet;
-}
-
-const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
-    const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine,
-    const long nXPos, const sal_Bool bRight )
-{
-    SwRect aRet;
-    MSHORT nPos = 0; // Suche im Cache ...
-    while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
-        ++nPos;
-    if( GetCount() == nPos ) // nicht gefunden
-    {
-        if( nObjCnt == POLY_CNT )
-        {
-            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
-            delete pTextRanger[ nObjCnt ];
-        }
-        ::basegfx::B2DPolyPolygon aPolyPolygon;
-        ::basegfx::B2DPolyPolygon* pPolyPolygon = 0L;
-
-        if ( pObj->ISA(SwVirtFlyDrawObj) )
-        {
-            // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik,
-            // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein
-            // ClrObject() auf.
-            PolyPolygon aPoly;
-            if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
-                aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
-                                     GetFlyFrm()->Frm().SVRect() );
-            aPolyPolygon.clear();
-            aPolyPolygon.append(aPoly.getB2DPolyPolygon());
-        }
-        else
-        {
-            if( !pObj->ISA( E3dObject ) )
-            {
-                aPolyPolygon = pObj->TakeXorPoly();
-            }
-
-            ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
-            pPolyPolygon = new ::basegfx::B2DPolyPolygon(aContourPoly);
-        }
-        const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
-        const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
-        memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
-        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
-        pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem
-                             // GetContour() eingetragen werden.
-        pTextRanger[ 0 ] = new TextRanger( aPolyPolygon, pPolyPolygon, 20,
-            (sal_uInt16)rLRSpace.GetLeft(), (sal_uInt16)rLRSpace.GetRight(),
-            pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() );
-        pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
-        pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
-
-        delete pPolyPolygon;
-        // UPPER_LOWER_TEST
-#ifdef DBG_UTIL
-        const ViewShell* pTmpViewShell = pFmt->GetDoc()->GetCurrentViewShell();
-        if( pTmpViewShell )
-        {
-            sal_Bool bT2 = pTmpViewShell->GetViewOptions()->IsTest2();
-            sal_Bool bT6 = pTmpViewShell->GetViewOptions()->IsTest6();
-            if( bT2 || bT6 )
-            {
-                if( bT2 )
-                    pTextRanger[ 0 ]->SetFlag7( sal_True );
-                else
-                    pTextRanger[ 0 ]->SetFlag6( sal_True );
-            }
-        }
-#endif
-        nPntCnt += pTextRanger[ 0 ]->GetPointCount();
-        while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
-        {
-            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
-            delete pTextRanger[ nObjCnt ];
-        }
-    }
-    else if( nPos )
-    {
-        const SdrObject* pTmpObj = pSdrObj[ nPos ];
-        TextRanger* pTmpRanger = pTextRanger[ nPos ];
-        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
-        memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
-        pSdrObj[ 0 ] = pTmpObj;
-        pTextRanger[ 0 ] = pTmpRanger;
-    }
-    SWRECTFN( pFrm )
-    long nTmpTop = (rLine.*fnRect->fnGetTop)();
-    // fnGetBottom is top + height
-    long nTmpBottom = (rLine.*fnRect->fnGetBottom)();
-
-    Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) );
-
-    LongDqPtr pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
-
-    MSHORT nCount;
-    if( 0 != ( nCount = pTmp->size() ) )
-    {
-        MSHORT nIdx = 0;
-        while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
-            ++nIdx;
-        sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
-        sal_Bool bSet = sal_True;
-        if( bOdd )
-            --nIdx; // innerhalb eines Intervalls
-        else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
-        {
-            if( nIdx )
-                nIdx -= 2; // ein Intervall nach links gehen
-            else
-                bSet = sal_False; // vor dem erstem Intervall
-        }
-
-        if( bSet && nIdx < nCount )
-        {
-            (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(),
-                                               (rLine.*fnRect->fnGetHeight)() );
-            (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] );
-            (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 );
-        }
-    }
-    return aRet;
-}
-
-/*************************************************************************
- *                      SwTxtFly::ForEach()
- *
- * sucht nach dem ersten Objekt, welches mit dem Rechteck ueberlappt
- *
- *************************************************************************/
 
 sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const
 {
@@ -1817,11 +1124,6 @@ sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid
     return bRet;
 }
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list