editeng/source/editeng/editeng.cxx               |   23 ++-
 editeng/source/editeng/editobj.cxx               |   11 +
 editeng/source/editeng/editobj2.hxx              |   14 +-
 editeng/source/editeng/impedit.hxx               |   98 +++++++--------
 editeng/source/editeng/impedit2.cxx              |   29 ++--
 editeng/source/editeng/impedit3.cxx              |  148 ++++++++++++++---------
 editeng/source/editeng/impedit4.cxx              |   24 +++
 editeng/source/outliner/outlin2.cxx              |   14 +-
 editeng/source/outliner/outliner.cxx             |   23 ++-
 include/editeng/editeng.hxx                      |    8 -
 include/editeng/outliner.hxx                     |    6 
 include/oox/export/drawingml.hxx                 |    2 
 include/svx/sdtfsitm.hxx                         |   20 +--
 include/svx/svdotext.hxx                         |    6 
 include/svx/unoshprp.hxx                         |    2 
 oox/inc/drawingml/textparagraph.hxx              |    3 
 oox/inc/drawingml/textparagraphproperties.hxx    |    1 
 oox/source/drawingml/diagram/diagram.cxx         |    6 
 oox/source/drawingml/textbody.cxx                |    4 
 oox/source/drawingml/textparagraph.cxx           |    4 
 oox/source/drawingml/textparagraphproperties.cxx |   10 -
 oox/source/export/drawingml.cxx                  |   45 +++---
 sd/qa/unit/export-tests-ooxml2.cxx               |   16 +-
 sd/qa/unit/export-tests-ooxml3.cxx               |   11 -
 sd/qa/unit/import-tests-smartart.cxx             |    8 -
 sd/qa/unit/import-tests2.cxx                     |   14 +-
 sd/source/ui/view/drtxtob.cxx                    |   10 -
 svx/source/svdraw/svdotext.cxx                   |  137 +++++++++++++++++++--
 svx/source/svdraw/svdotextdecomposition.cxx      |    2 
 svx/source/svdraw/svdoutl.cxx                    |    2 
 svx/source/unodraw/unoshape.cxx                  |    9 -
 31 files changed, 452 insertions(+), 258 deletions(-)

New commits:
commit 628275acb1b9652e65b8c5c013549dce5ad6f5bf
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Mar 23 11:24:30 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Sun Mar 26 15:07:39 2023 +0000

    tdf#90407 Change the auto-fit alg. to match better with OOXML
    
    The auto-fit algorithm has been tweaked to be more in-line with
    the expectations of OOXML. This means a couple of changes to what
    properties are scaled by the algorithm have been made:
    - most properties that influence the X axis position or size (for
    example indent) are not scaled down or changed by scaling.
    - properties that influence y axis position and size are scaled
    by a separate parameter (like in the OOXML). This is used in the
    auto-fit algorithm in a different way.
    - if line spacing is proportional, it is now scaled with the
    spacing parameter. Fixed line spacing doesn't get scaled.
    - the main scaling X,Y parameter only scales the fonts.
    - trying hard to scale the fonts to the nearest pt (point) value
    
    With this change the scaling is much more stable than it was
    before - for example it doesn't matter what the unscaled font
    size is, when it is scaled down to the text box size, it (should)
    always look the same (for example scaling from 32pt -> 10pt or
    64pt -> 10pt or even 999pt -> 10pt).
    
    The algorithm is also rewritten to be better at finding a fit and
    is also better at find a good fit, but it can take more iterations
    by doing so (there are ways to improve it however). Previous
    algorithm used a linear search to converge to the best fit in less
    iterations, but the issue with that was that it could in some cases
    miss a solution (especially since change to floating point scaling
    parameter). The new algorithm now uses a binary search - always
    trying the middle of the search space.
    
    OOXML export and import was also changed to take advantage of the
    font scaling and spacing scaling parameters. The additional
    scaling at export that was needed to have consistent OOXML support
    was removed.
    
    Change-Id: I8f3bb8d43a01931f18bd7ffdf8e0ba40caa73d8b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149207
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index 32fad4d8fc35..69fef679c7f3 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -2006,14 +2006,13 @@ Point EditEngine::GetDocPosTopLeft( sal_Int32 
nParagraph )
         else
         {
             const SvxLRSpaceItem& rLRItem = pImpEditEngine->GetLRSpaceItem( 
pPPortion->GetNode() );
-// TL_NF_LR         aPoint.X() = pImpEditEngine->GetXValue( 
(short)(rLRItem.GetTextLeft() + rLRItem.GetTextFirstLineOffset()) );
             sal_Int32 nSpaceBefore = 0;
             pImpEditEngine->GetSpaceBeforeAndMinLabelWidth( 
pPPortion->GetNode(), &nSpaceBefore );
             short nX = static_cast<short>(rLRItem.GetTextLeft()
                             + rLRItem.GetTextFirstLineOffset()
                             + nSpaceBefore);
-            aPoint.setX( pImpEditEngine->GetXValue( nX
-                             ) );
+
+            aPoint.setX(pImpEditEngine->scaleXSpacingValue(nX));
         }
         aPoint.setY( pImpEditEngine->GetParaPortions().GetYOffset( pPPortion ) 
);
     }
@@ -2266,14 +2265,24 @@ bool EditEngine::HasText( const SvxSearchItem& 
rSearchItem )
     return pImpEditEngine->HasText( rSearchItem );
 }
 
-void EditEngine::SetGlobalCharStretching(double nX, double nY)
+void EditEngine::setGlobalScale(double fFontScaleX, double fFontScaleY, double 
fSpacingScaleX, double fSpacingScaleY)
+{
+    pImpEditEngine->setScale(fFontScaleX, fFontScaleY, fSpacingScaleX, 
fSpacingScaleY);
+}
+
+void EditEngine::getGlobalSpacingScale(double& rX, double& rY) const
+{
+    pImpEditEngine->getSpacingScale(rX, rY);
+}
+
+void EditEngine::getGlobalFontScale(double& rX, double& rY) const
 {
-    pImpEditEngine->SetCharStretching( nX, nY );
+    pImpEditEngine->getFontScale(rX, rY);
 }
 
-void EditEngine::GetGlobalCharStretching(double& rX, double& rY) const
+void EditEngine::setRoundFontSizeToPt(bool bRound) const
 {
-    pImpEditEngine->GetCharStretching( rX, rY );
+    pImpEditEngine->setRoundToNearestPt(bRound);
 }
 
 bool EditEngine::ShouldCreateBigTextObject() const
diff --git a/editeng/source/editeng/editobj.cxx 
b/editeng/source/editeng/editobj.cxx
index 437754d70def..d0ec8632f134 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -70,11 +70,14 @@ void XEditAttribute::SetItem(const SfxPoolItem& rNew)
     pItem = &rNew;
 }
 
-XParaPortionList::XParaPortionList(
-    OutputDevice* pRefDev, sal_uInt32 nPW, double nStretchX, double nStretchY)
+XParaPortionList::XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW,
+            double fFontScaleX, double fFontScaleY,
+            double fSpacingScaleX, double fSpacingScaleY)
     : pRefDevPtr(pRefDev)
-    , mnStretchX(nStretchX)
-    , mnStretchY(nStretchY)
+    , mfFontScaleX(fFontScaleX)
+    , mfFontScaleY(fFontScaleY)
+    , mfSpacingScaleX(fSpacingScaleX)
+    , mfSpacingScaleY(fSpacingScaleY)
     , nPaperWidth(nPW)
 {
 }
diff --git a/editeng/source/editeng/editobj2.hxx 
b/editeng/source/editeng/editobj2.hxx
index 86a2e379be20..86c81e23f94e 100644
--- a/editeng/source/editeng/editobj2.hxx
+++ b/editeng/source/editeng/editobj2.hxx
@@ -94,12 +94,14 @@ class XParaPortionList
     ListType maList;
 
     VclPtr<OutputDevice> pRefDevPtr;
-    double  mnStretchX;
-    double  mnStretchY;
+    double  mfFontScaleX;
+    double  mfFontScaleY;
+    double  mfSpacingScaleX;
+    double  mfSpacingScaleY;
     sal_uInt32  nPaperWidth;
 
 public:
-    XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW, double nStretchX, 
double nStretchY);
+    XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW, double 
fFontScaleX, double fFontScaleY, double fSpacingScaleX, double fSpacingScaleY);
 
     void push_back(XParaPortion* p);
     const XParaPortion& operator[](size_t i) const;
@@ -108,8 +110,10 @@ public:
     sal_uInt32          GetPaperWidth() const       { return nPaperWidth; }
     bool                RefDevIsVirtual() const {return 
pRefDevPtr->IsVirtual();}
     const MapMode&  GetRefMapMode() const       { return 
pRefDevPtr->GetMapMode(); }
-    double  GetStretchX() const { return mnStretchX; }
-    double  GetStretchY() const { return mnStretchY; }
+    double  getFontScaleX() const { return mfFontScaleX; }
+    double  getFontScaleY() const { return mfFontScaleY; }
+    double  getSpacingScaleX() const { return mfSpacingScaleX; }
+    double  getSpacingScaleY() const { return mfSpacingScaleY; }
 };
 
 class ContentInfo
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index fd8ff61f66ca..7bbd0fd9e765 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -528,8 +528,11 @@ private:
 
     Color               maBackgroundColor;
 
-    double mnStretchX;
-    double mnStretchY;
+    double mfFontScaleX;
+    double mfFontScaleY;
+    double mfSpacingScaleX;
+    double mfSpacingScaleY;
+    bool mbRoundToNearestPt;
 
     CharCompressType    nAsianCompressionMode;
 
@@ -733,11 +736,40 @@ private:
                             std::vector<std::unique_ptr<SvxFontItem>>& 
rFontTable, SvxColorList& rColorList );
     sal_Int32           LogicToTwips( sal_Int32 n );
 
-    inline short        GetXValue( short nXValue ) const;
-    inline tools::Long         GetXValue( tools::Long nXValue ) const;
+    double scaleXSpacingValue(tools::Long nXValue) const
+    {
+        if (!aStatus.DoStretch() || mfSpacingScaleX == 100.0)
+            return nXValue;
+
+        return double(nXValue) * mfSpacingScaleX / 100.0;
+    }
 
-    inline short        GetYValue( short nYValue ) const;
-    inline sal_uInt16   GetYValue( sal_uInt16 nYValue ) const;
+    double scaleYSpacingValue(sal_uInt16 nYValue) const
+    {
+        if (!aStatus.DoStretch() || mfSpacingScaleY == 100.0)
+            return nYValue;
+
+        return double(nYValue) * mfSpacingScaleY / 100.0;
+    }
+
+    double scaleYFontValue(sal_uInt16 nYValue) const
+    {
+        if (!aStatus.DoStretch() || (mfFontScaleY == 100.0))
+            return nYValue;
+
+        return double(nYValue) * mfFontScaleY / 100.0;
+    }
+
+    double scaleXFontValue(tools::Long nXValue) const
+    {
+        if (!aStatus.DoStretch() || (mfFontScaleX == 100.0))
+            return nXValue;
+
+        return double(nXValue) * mfFontScaleY / 100.0;
+    }
+
+    void setRoundToNearestPt(bool bRound) { mbRoundToNearestPt = bRound; }
+    double roundToNearestPt(double fInput) const;
 
     ContentNode*        GetPrevVisNode( ContentNode const * pCurNode );
     ContentNode*        GetNextVisNode( ContentNode const * pCurNode );
@@ -1080,8 +1112,19 @@ public:
     SvxCellJustifyMethod    GetJustifyMethod( sal_Int32 nPara ) const;
     SvxCellVerJustify       GetVerJustification( sal_Int32 nPara ) const;
 
-    void                SetCharStretching(double nX, double nY);
-    inline void         GetCharStretching(double& rX, double& rY) const;
+    void setScale(double fFontScaleX, double fFontScaleY, double 
fSpacingScaleX, double fSpacingScaleY);
+
+    void getFontScale(double& rX, double& rY) const
+    {
+        rX = mfFontScaleX;
+        rY = mfFontScaleY;
+    }
+
+    void getSpacingScale(double& rX, double& rY) const
+    {
+        rX = mfSpacingScaleX;
+        rY = mfSpacingScaleY;
+    }
 
     sal_Int32           GetBigTextObjectStart() const                          
     { return nBigTextObjectStart; }
 
@@ -1282,45 +1325,6 @@ inline ParaPortion* ImpEditEngine::FindParaPortion( 
ContentNode const * pNode )
     return GetParaPortions()[ nPos ];
 }
 
-inline void ImpEditEngine::GetCharStretching(double& rX, double& rY) const
-{
-    rX = mnStretchX;
-    rY = mnStretchY;
-}
-
-inline short ImpEditEngine::GetXValue( short nXValue ) const
-{
-    if ( !aStatus.DoStretch() || ( mnStretchX == 100.0 ) )
-        return nXValue;
-
-    return basegfx::fround(double(nXValue) * mnStretchX / 100.0);
-}
-
-
-inline tools::Long ImpEditEngine::GetXValue( tools::Long nXValue ) const
-{
-    if ( !aStatus.DoStretch() || ( mnStretchX == 100.0 ) )
-        return nXValue;
-
-    return basegfx::fround(nXValue * mnStretchX / 100.0);
-}
-
-inline short ImpEditEngine::GetYValue( short nYValue ) const
-{
-    if ( !aStatus.DoStretch() || ( mnStretchY == 100.0 ) )
-        return nYValue;
-
-    return basegfx::fround(double(nYValue) * mnStretchY / 100.0);
-}
-
-inline sal_uInt16 ImpEditEngine::GetYValue( sal_uInt16 nYValue ) const
-{
-    if ( !aStatus.DoStretch() || ( mnStretchY == 100.0 ) )
-        return nYValue;
-
-    return basegfx::fround(double(nYValue) * mnStretchY / 100.0);
-}
-
 inline PointerStyle ImpEditView::GetPointer()
 {
     if ( !mxPointer )
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 4e87e36af5d3..e6cbdcfbdeb9 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -98,8 +98,11 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* 
pItemPool ) :
     pUndoManager(nullptr),
     aWordDelimiters(" .,;:-`'?!_=\"{}()[]"),
     maBackgroundColor(COL_AUTO),
-    mnStretchX(100.0),
-    mnStretchY(100.0),
+    mfFontScaleX(100.0),
+    mfFontScaleY(100.0),
+    mfSpacingScaleX(100.0),
+    mfSpacingScaleY(100.0),
+    mbRoundToNearestPt(false),
     nAsianCompressionMode(CharCompressType::NONE),
     eDefaultHorizontalTextDirection(EEHorizontalTextDirection::Default),
     nBigTextObjectStart(20),
@@ -3222,7 +3225,7 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
                 const SvxLineSpacingItem& rLSItem
                     = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
                 nSBL = (rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix)
-                           ? GetYValue(rLSItem.GetInterLineSpace())
+                           ? scaleYSpacingValue(rLSItem.GetInterLineSpace())
                            : 0;
             }
 
@@ -3266,7 +3269,7 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
             {
                 const SvxULSpaceItem& rULItem
                     = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_ULSPACE);
-                tools::Long nUL = GetYValue(rULItem.GetLower());
+                tools::Long nUL = scaleYSpacingValue(rULItem.GetLower());
                 adjustYDirectionAware(aLineStart, nUL);
             }
         }
@@ -3402,10 +3405,10 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 
nPara, bool bIgnoreExtraSpace
             // width, here not preferred. I general, it is best not leave it
             // to StartPosX, also the right indents have to be taken into
             // account!
-            tools::Long nCurWidth = GetXValue( rLRItem.GetTextLeft() + 
nSpaceBeforeAndMinLabelWidth );
+            tools::Long nCurWidth = scaleXSpacingValue(rLRItem.GetTextLeft() + 
nSpaceBeforeAndMinLabelWidth);
             if ( nLine == 0 )
             {
-                tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() 
);
+                tools::Long nFI = 
scaleXSpacingValue(rLRItem.GetTextFirstLineOffset());
                 nCurWidth -= nFI;
                 if ( pPortion->GetBulletX() > nCurWidth )
                 {
@@ -3414,7 +3417,7 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 nPara, 
bool bIgnoreExtraSpace
                         nCurWidth = pPortion->GetBulletX();
                 }
             }
-            nCurWidth += GetXValue( rLRItem.GetRight() );
+            nCurWidth += scaleXSpacingValue(rLRItem.GetRight());
             nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace );
             if ( nCurWidth > nMaxWidth )
             {
@@ -4337,7 +4340,7 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
 
     const SvxULSpaceItem& rULItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
     const SvxLineSpacingItem& rLSItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
-    sal_Int32 nSBL = ( rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix ) ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+    sal_Int32 nSBL = ( rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix ) ? scaleYSpacingValue(rLSItem.GetInterLineSpace()) 
: 0;
 
     if ( nSBL )
     {
@@ -4350,14 +4353,14 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
     sal_Int32 nPortion = GetParaPortions().GetPos( pPortion );
     if ( nPortion )
     {
-        sal_uInt16 nUpper = GetYValue( rULItem.GetUpper() );
+        sal_uInt16 nUpper = scaleYSpacingValue(rULItem.GetUpper());
         pPortion->nHeight += nUpper;
         pPortion->nFirstLineOffset = nUpper;
     }
 
     if ( nPortion != (GetParaPortions().Count()-1) )
     {
-        pPortion->nHeight += GetYValue( rULItem.GetLower() );   // not in the 
last
+        pPortion->nHeight += scaleYSpacingValue(rULItem.GetLower());   // not 
in the last
     }
 
 
@@ -4377,7 +4380,7 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
     // Only Writer3: Do not add up, but minimum distance.
 
     // check if distance by LineSpacing > Upper:
-    sal_uInt16 nExtraSpace = GetYValue( lcl_CalcExtraSpace( rLSItem ) );
+    sal_uInt16 nExtraSpace = scaleYSpacingValue(lcl_CalcExtraSpace(rLSItem));
     if ( nExtraSpace > pPortion->nFirstLineOffset )
     {
         // Paragraph becomes 'bigger':
@@ -4386,7 +4389,7 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
     }
 
     // Determine nFirstLineOffset now f(pNode) => now f(pNode, pPrev):
-    sal_uInt16 nPrevLower = GetYValue( rPrevULItem.GetLower() );
+    sal_uInt16 nPrevLower = scaleYSpacingValue(rPrevULItem.GetLower());
 
     // This PrevLower is still in the height of PrevPortion ...
     if ( nPrevLower > pPortion->nFirstLineOffset )
@@ -4408,7 +4411,7 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
     if ( pPrev->IsInvalid() )
         return;
 
-    nExtraSpace = GetYValue( lcl_CalcExtraSpace( rPrevLSItem ) );
+    nExtraSpace = scaleYSpacingValue(lcl_CalcExtraSpace(rPrevLSItem));
     if ( nExtraSpace > nPrevLower )
     {
         sal_uInt16 nMoreLower = nExtraSpace - nPrevLower;
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index 376d1df7ad13..6cb45a385748 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -668,7 +668,8 @@ void ImpEditEngine::CheckPageOverflow()
 
 static sal_Int32 ImplCalculateFontIndependentLineSpacing( const sal_Int32 
nFontHeight )
 {
-    return ( nFontHeight * 12 ) / 10;   // + 20%
+    constexpr const double f120Percent = 12.0 / 10.0;
+    return basegfx::fround(nFontHeight * f120Percent);  // + 20%
 }
 
 tools::Long ImpEditEngine::GetColumnWidth(const Size& rPaperSize) const
@@ -827,7 +828,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     {
         aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( pParaPortion ) );
         if ( !aBulletArea.IsWidthEmpty() && aBulletArea.Right() > 0 )
-            pParaPortion->SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
+            
pParaPortion->SetBulletX(sal_Int32(scaleXSpacingValue(aBulletArea.Right())));
         else
             pParaPortion->SetBulletX( 0 ); // if Bullet is set incorrectly
     }
@@ -861,10 +862,10 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         sal_Int32 nPortionStart = 0;
         sal_Int32 nPortionEnd = 0;
 
-        tools::Long nStartX = GetXValue( rLRItem.GetTextLeft() + 
nSpaceBeforeAndMinLabelWidth );
+        tools::Long nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + 
nSpaceBeforeAndMinLabelWidth);
         if ( nIndex == 0 )
         {
-            tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() );
+            tools::Long nFI = 
scaleXSpacingValue(rLRItem.GetTextFirstLineOffset());
             nStartX += nFI;
 
             if ( !nLine && ( pParaPortion->GetBulletX() > nStartX ) )
@@ -876,13 +877,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         const bool bAutoSize = IsEffectivelyVertical() ? 
aStatus.AutoPageHeight() : aStatus.AutoPageWidth();
         tools::Long nMaxLineWidth = GetColumnWidth(bAutoSize ? 
aMaxAutoPaperSize : aPaperSize);
 
-        nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
+        nMaxLineWidth -= scaleXSpacingValue(rLRItem.GetRight());
         nMaxLineWidth -= nStartX;
 
         // If PaperSize == long_max, one cannot take away any negative
         // first line indent. (Overflow)
         if ( ( nMaxLineWidth < 0 ) && ( nStartX < 0 ) )
-            nMaxLineWidth = GetColumnWidth(aPaperSize) - 
GetXValue(rLRItem.GetRight());
+            nMaxLineWidth = GetColumnWidth(aPaperSize) - 
scaleXSpacingValue(rLRItem.GetRight());
 
         // If still less than 0, it may be just the right edge.
         if ( nMaxLineWidth <= 0 )
@@ -962,7 +963,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 }
                 nXWidth = nMaxRangeWidth;
                 if ( nXWidth )
-                    nMaxLineWidth = nXWidth - nStartX - GetXValue( 
rLRItem.GetRight() );
+                    nMaxLineWidth = nXWidth - nStartX - 
scaleXSpacingValue(rLRItem.GetRight());
                 else
                 {
                     // Try further down in the polygon.
@@ -1052,14 +1053,14 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                         tools::Long nOldTmpWidth = nTmpWidth;
 
                         // Search for Tab-Pos...
-                        tools::Long nCurPos = nTmpWidth+nStartX;
+                        tools::Long nCurPos = nTmpWidth + nStartX;
                         // consider scaling
-                        if ( aStatus.DoStretch() && ( mnStretchX != 100.0 ) )
-                            nCurPos = basegfx::fround(double(nCurPos) * 100.0 
/ std::max(mnStretchX, 1.0));
+                        if (aStatus.DoStretch() && (mfFontScaleX != 100.0))
+                            nCurPos = basegfx::fround(double(nCurPos) * 100.0 
/ std::max(mfFontScaleX, 1.0));
 
                         short nAllSpaceBeforeText = static_cast< short 
>(rLRItem.GetTextLeft()/* + rLRItem.GetTextLeft()*/ + 
nSpaceBeforeAndMinLabelWidth);
                         aCurrentTab.aTabStop = 
pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText 
/*rLRItem.GetTextLeft()*/, aEditDoc.GetDefTab() );
-                        aCurrentTab.nTabPos = GetXValue( 
static_cast<tools::Long>( aCurrentTab.aTabStop.GetTabPos() + 
nAllSpaceBeforeText /*rLRItem.GetTextLeft()*/ ) );
+                        aCurrentTab.nTabPos = 
scaleXFontValue(tools::Long(aCurrentTab.aTabStop.GetTabPos() + 
nAllSpaceBeforeText/*rLRItem.GetTextLeft()*/));
                         aCurrentTab.bValid = false;
 
                         // Switch direction in R2L para...
@@ -1286,8 +1287,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     // No spacing within L2R/R2L nesting
                     if ( bAllow )
                     {
-                        tools::Long nExtraSpace = 
pPortion->GetSize().Height()/5;
-                        nExtraSpace = GetXValue( nExtraSpace );
+                        tools::Long nExtraSpace = pPortion->GetSize().Height() 
/ 5;
+                        nExtraSpace = scaleXSpacingValue(nExtraSpace);
                         pPortion->adjustSize(nExtraSpace, 0);
                         nTmpWidth += nExtraSpace;
                     }
@@ -1500,12 +1501,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             bSameLineAgain = true;
         }
 
-
         if ( !bSameLineAgain && !aStatus.IsOutliner() )
         {
             if ( rLSItem.GetLineSpaceRule() == SvxLineSpaceRule::Min )
             {
-                sal_uInt16 nMinHeight = GetYValue( rLSItem.GetLineHeight() );
+                double fMinHeight = 
scaleYSpacingValue(rLSItem.GetLineHeight());
+                sal_uInt16 nMinHeight = basegfx::fround(fMinHeight);
+
                 sal_uInt16 nTxtHeight = pLine->GetHeight();
                 if ( nTxtHeight < nMinHeight )
                 {
@@ -1517,7 +1519,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             }
             else if ( rLSItem.GetLineSpaceRule() == SvxLineSpaceRule::Fix )
             {
-                sal_uInt16 nFixHeight = GetYValue( rLSItem.GetLineHeight() );
+                double fFixHeight = 
scaleYSpacingValue(rLSItem.GetLineHeight());
+                sal_uInt16 nFixHeight = basegfx::fround(fFixHeight);
+
                 sal_uInt16 nTxtHeight = pLine->GetHeight();
                 pLine->SetMaxAscent( 
static_cast<sal_uInt16>(pLine->GetMaxAscent() + ( nFixHeight - nTxtHeight ) ) );
                 pLine->SetHeight( nFixHeight, nTxtHeight );
@@ -1526,29 +1530,51 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             {
                 // There are documents with PropLineSpace 0, why?
                 // (cmc: re above question :-) such documents can be seen by 
importing a .ppt
-                if ( rLSItem.GetPropLineSpace() && ( 
rLSItem.GetPropLineSpace() < 100 ) )
+                sal_uInt16 nPropLineSpace = rLSItem.GetPropLineSpace();
+                double fProportionalScale = double(nPropLineSpace) / 100.0;
+                constexpr const double f80Percent = 8.0 / 10.0;
+                double fSpacingFactor = mfSpacingScaleY / 100.0;
+                if (nPropLineSpace && nPropLineSpace < 100)
                 {
                     // Adapted code from sw/source/core/text/itrform2.cxx
-                    sal_uInt16 nPropLineSpace = rLSItem.GetPropLineSpace();
                     sal_uInt16 nAscent = pLine->GetMaxAscent();
-                    sal_uInt16 nNewAscent = pLine->GetTxtHeight() * 
nPropLineSpace / 100 * 4 / 5; // 80%
-                    if ( !nAscent || nAscent > nNewAscent )
-                    {
-                        pLine->SetMaxAscent( nNewAscent );
-                    }
-                    sal_uInt16 nHeight = pLine->GetHeight() * nPropLineSpace / 
100;
-                    pLine->SetHeight( nHeight, pLine->GetTxtHeight() );
+                    sal_uInt16 nNewAscent = 
basegfx::fround(pLine->GetTxtHeight() * fSpacingFactor * fProportionalScale * 
f80Percent);
+                    if (!nAscent || nAscent > nNewAscent)
+                        pLine->SetMaxAscent(nNewAscent);
+                    sal_uInt16 nHeight = basegfx::fround(pLine->GetHeight() * 
fProportionalScale * fSpacingFactor);
+
+                    pLine->SetHeight(nHeight, pLine->GetTxtHeight());
                 }
-                else if ( rLSItem.GetPropLineSpace() && ( 
rLSItem.GetPropLineSpace() != 100 ) )
+                else if (nPropLineSpace && nPropLineSpace != 100)
                 {
                     sal_uInt16 nTxtHeight = pLine->GetHeight();
-                    sal_Int32 nPropTextHeight = nTxtHeight * 
rLSItem.GetPropLineSpace() / 100;
+                    sal_Int32 nPropTextHeight = nTxtHeight * 
fProportionalScale * fSpacingFactor;
                     // The Ascent has to be adjusted for the difference:
                     tools::Long nDiff = pLine->GetHeight() - nPropTextHeight;
                     pLine->SetMaxAscent( static_cast<sal_uInt16>( 
pLine->GetMaxAscent() - nDiff ) );
                     pLine->SetHeight( static_cast<sal_uInt16>( nPropTextHeight 
), nTxtHeight );
                 }
             }
+            else if (rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Off)
+            {
+                if (mfSpacingScaleY < 100.0)
+                {
+                    double fSpacingFactor = mfSpacingScaleY / 100.0;
+                    sal_uInt16 nPropLineSpace = basegfx::fround(100.0 * 
fSpacingFactor);
+                    if (nPropLineSpace && nPropLineSpace < 100)
+                    {
+                        // Adapted code from sw/source/core/text/itrform2.cxx
+                        sal_uInt16 nAscent = pLine->GetMaxAscent();
+                        sal_uInt16 nNewAscent = 
basegfx::fround(pLine->GetTxtHeight() * fSpacingFactor);
+                        if (!nAscent || nAscent > nNewAscent)
+                            pLine->SetMaxAscent(nNewAscent);
+                        sal_uInt16 nHeight = 
basegfx::fround(pLine->GetHeight() * fSpacingFactor);
+
+                        pLine->SetHeight(nHeight, pLine->GetTxtHeight());
+                    }
+
+                }
+            }
         }
 
         if ( ( !IsEffectivelyVertical() && aStatus.AutoPageWidth() ) ||
@@ -1558,8 +1584,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             // has to be used for the Alignment. If it does not fit or if it
             // will change the paper width, it will be formatted again for
             // Justification! = LEFT anyway.
-            tools::Long nMaxLineWidthFix = GetColumnWidth(aPaperSize)
-                                        - GetXValue( rLRItem.GetRight() ) - 
nStartX;
+            tools::Long nMaxLineWidthFix = GetColumnWidth(aPaperSize) - 
scaleXSpacingValue(rLRItem.GetRight()) - nStartX;
             if ( aTextSize.Width() < nMaxLineWidthFix )
                 nMaxLineWidth = nMaxLineWidthFix;
         }
@@ -1784,23 +1809,23 @@ void ImpEditEngine::CreateAndInsertEmptyLine( 
ParaPortion* pParaPortion )
     sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( 
pParaPortion->GetNode(), &nSpaceBefore );
     const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pParaPortion->GetNode() );
     const SvxLineSpacingItem& rLSItem = 
pParaPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
-    tools::Long nStartX = GetXValue( rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBefore );
+    tools::Long nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBefore);
 
     tools::Rectangle aBulletArea { Point(), Point() };
     if ( bLineBreak )
     {
-        nStartX = GetXValue( rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBeforeAndMinLabelWidth );
+        nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBeforeAndMinLabelWidth);
     }
     else
     {
         aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( pParaPortion ) );
         if ( !aBulletArea.IsEmpty() && aBulletArea.Right() > 0 )
-            pParaPortion->SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
+            
pParaPortion->SetBulletX(sal_Int32(scaleXSpacingValue(aBulletArea.Right())));
         else
             pParaPortion->SetBulletX( 0 ); // If Bullet set incorrectly.
         if ( pParaPortion->GetBulletX() > nStartX )
         {
-            nStartX = GetXValue( rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBeforeAndMinLabelWidth );
+            nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + 
rLRItem.GetTextFirstLineOffset() + nSpaceBeforeAndMinLabelWidth);
             if ( pParaPortion->GetBulletX() > nStartX )
                 nStartX = pParaPortion->GetBulletX();
         }
@@ -1828,7 +1853,7 @@ void ImpEditEngine::CreateAndInsertEmptyLine( 
ParaPortion* pParaPortion )
         sal_Int32 nPara = GetParaPortions().GetPos( pParaPortion );
         SvxAdjust eJustification = GetJustification( nPara );
         tools::Long nMaxLineWidth = GetColumnWidth(aPaperSize);
-        nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
+        nMaxLineWidth -= scaleXSpacingValue(rLRItem.GetRight());
         if ( nMaxLineWidth < 0 )
             nMaxLineWidth = 1;
         if ( eJustification ==  SvxAdjust::Center )
@@ -2994,20 +3019,24 @@ void ImpEditEngine::SeekCursor( ContentNode* pNode, 
sal_Int32 nPos, SvxFont& rFo
 
         if ( aStatus.DoStretch() )
         {
-            if (mnStretchY != 100.0)
+            if (mfFontScaleY != 100.0)
             {
-                double fNewHeight = (double(aRealSz.Height()) * mnStretchY) / 
100.0;
+                double fHeightRounded = roundToNearestPt(aRealSz.Height());
+                double fNewHeight = fHeightRounded * (mfFontScaleY / 100.0);
+                fNewHeight = roundToNearestPt(fNewHeight);
                 aRealSz.setHeight(basegfx::fround(fNewHeight));
             }
-            if (mnStretchX != 100.0)
+            if (mfFontScaleX != 100.0)
             {
-                if (mnStretchX == mnStretchY && nRelWidth == 100 )
+                if (mfFontScaleX == mfFontScaleY && nRelWidth == 100 )
                 {
                     aRealSz.setWidth( 0 );
                 }
                 else
                 {
-                    double fNewWidth = (double(aRealSz.Width()) * mnStretchX) 
/ 100.0;
+                    double fWidthRounded = roundToNearestPt(aRealSz.Width());
+                    double fNewWidth = fWidthRounded * (mfFontScaleX / 100.0);
+                    fNewWidth = roundToNearestPt(fNewWidth);
                     aRealSz.setWidth(basegfx::fround(fNewWidth));
 
                     // Also the Kerning: (long due to handle Interim results)
@@ -3023,15 +3052,15 @@ void ImpEditEngine::SeekCursor( ContentNode* pNode, 
sal_Int32 nPos, SvxFont& rFo
   >0        >100        > (Proportional)
   <0        >100        < (The amount, thus disproportional)
 */
-                    if (nKerning < 0 && mnStretchX > 100.0)
+                    if (nKerning < 0 && mfFontScaleX > 100.0)
                     {
                         // disproportional
-                        nKerning = basegfx::fround((double(nKerning) * 100.0) 
/ mnStretchX);
+                        nKerning = basegfx::fround((double(nKerning) * 100.0) 
/ mfFontScaleX);
                     }
                     else if ( nKerning )
                     {
                         // Proportional
-                        nKerning = basegfx::fround((double(nKerning) * 
mnStretchX) / 100.0);
+                        nKerning = basegfx::fround((double(nKerning) * 
mfFontScaleX) / 100.0);
                     }
                     rFont.SetFixKerning( static_cast<short>(nKerning) );
                 }
@@ -3369,7 +3398,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
             const SvxLineSpacingItem& rLSItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
             sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix )
-                                ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+                                ? 
scaleYSpacingValue(rLSItem.GetInterLineSpace()) : 0;
             bool bPaintBullet (false);
 
             for ( sal_Int32 nLine = 0; nLine < nLines; nLine++ )
@@ -4033,7 +4062,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
             if ( !aStatus.IsOutliner() )
             {
                 const SvxULSpaceItem& rULItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
-                tools::Long nUL = GetYValue( rULItem.GetLower() );
+                tools::Long nUL = scaleYSpacingValue(rULItem.GetLower());
                 adjustYDirectionAware(aStartPos, nUL);
             }
 
@@ -4359,10 +4388,10 @@ tools::Long ImpEditEngine::CalcVertLineSpacing(Point& 
rStartPos) const
 
         const SvxLineSpacingItem& rLSItem = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
         sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix )
-                            ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+                            ? scaleYSpacingValue(rLSItem.GetInterLineSpace()) 
: 0;
 
         const SvxULSpaceItem& rULItem = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_ULSPACE);
-        tools::Long nUL = GetYValue( rULItem.GetLower() );
+        tools::Long nUL = scaleYSpacingValue(rULItem.GetLower());
 
         const EditLineList& rLines = pPortion->GetLines();
         sal_Int32 nLineCount = rLines.Count();
@@ -4459,28 +4488,35 @@ void ImpEditEngine::SetFlatMode( bool bFlat )
         pActiveView->ShowCursor();
 }
 
-void ImpEditEngine::SetCharStretching(double nX, double nY)
+void ImpEditEngine::setScale(double fFontScaleX, double fFontScaleY, double 
fSpacingScaleX, double fSpacingScaleY)
 {
     bool bChanged;
-    if ( !IsEffectivelyVertical() )
+
+    if (!IsEffectivelyVertical())
     {
-        bChanged = mnStretchX != nX || mnStretchY != nY;
-        mnStretchX = nX;
-        mnStretchY = nY;
+        bChanged = mfFontScaleX != fFontScaleX || mfFontScaleY != fFontScaleY 
||
+                   mfSpacingScaleX != fSpacingScaleX || mfSpacingScaleY != 
fSpacingScaleY;
+        mfFontScaleX = fFontScaleX;
+        mfFontScaleY = fFontScaleY;
+        mfSpacingScaleX = fSpacingScaleX;
+        mfSpacingScaleY = fSpacingScaleY;
     }
     else
     {
-        bChanged = mnStretchX != nY || mnStretchY != nX;
-        mnStretchX = nY;
-        mnStretchY = nX;
+        bChanged = mfFontScaleX != fFontScaleY || mfFontScaleY != fFontScaleX 
||
+                   mfSpacingScaleX != fSpacingScaleY || mfSpacingScaleY != 
fSpacingScaleX;
+        mfFontScaleX = fFontScaleY;
+        mfFontScaleY = fFontScaleX;
+        mfSpacingScaleX = fSpacingScaleY;
+        mfSpacingScaleY = fSpacingScaleX;
     }
 
     if (bChanged && aStatus.DoStretch())
     {
         FormatFullDoc();
         // (potentially) need everything redrawn
-        aInvalidRect=tools::Rectangle(0,0,1000000,1000000);
-        UpdateViews( GetActiveView() );
+        aInvalidRect = tools::Rectangle(0, 0, 1000000, 1000000);
+        UpdateViews(GetActiveView());
     }
 }
 
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index 5affeff55455..424b43aadaeb 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -1093,7 +1093,7 @@ std::unique_ptr<EditTextObject> 
ImpEditEngine::CreateTextObject( EditSelection a
     // sleeper set up when Olli paragraphs not hacked!
     if ( bAllowBigObjects && bOnlyFullParagraphs && IsFormatted() && 
IsUpdateLayout() && ( nTextPortions >= nBigObjectStart ) )
     {
-        XParaPortionList* pXList = new XParaPortionList( GetRefDevice(), 
GetColumnWidth(aPaperSize), mnStretchX, mnStretchY );
+        XParaPortionList* pXList = new XParaPortionList(GetRefDevice(), 
GetColumnWidth(aPaperSize), mfFontScaleX, mfFontScaleY, mfSpacingScaleX, 
mfSpacingScaleY);
         pTxtObj->SetPortionInfo(std::unique_ptr<XParaPortionList>(pXList));
         for ( nNode = nStartNode; nNode <= nEndNode; nNode++  )
         {
@@ -1178,9 +1178,11 @@ EditSelection ImpEditEngine::InsertTextObject( const 
EditTextObject& rTextObject
     XParaPortionList* pPortionInfo = rTextObjectImpl.GetPortionInfo();
 
     if ( pPortionInfo && ( 
static_cast<tools::Long>(pPortionInfo->GetPaperWidth()) == 
GetColumnWidth(aPaperSize) )
-            && ( pPortionInfo->GetRefMapMode() == GetRefDevice()->GetMapMode() 
)
-            && ( pPortionInfo->GetStretchX() == mnStretchX)
-            && ( pPortionInfo->GetStretchY() == mnStretchY))
+            && pPortionInfo->GetRefMapMode() == GetRefDevice()->GetMapMode()
+            && pPortionInfo->getFontScaleX() == mfFontScaleX
+            && pPortionInfo->getFontScaleY() == mfFontScaleY
+            && pPortionInfo->getSpacingScaleX() == mfSpacingScaleX
+            && pPortionInfo->getSpacingScaleY() == mfSpacingScaleY)
     {
         if ( (pPortionInfo->GetRefDevPtr() == GetRefDevice()) ||
              (pPortionInfo->RefDevIsVirtual() && GetRefDevice()->IsVirtual()) )
@@ -3103,4 +3105,18 @@ sal_Int32 ImpEditEngine::LogicToTwips(sal_Int32 n)
     return aSz.Width();
 }
 
+double ImpEditEngine::roundToNearestPt(double fInput) const
+{
+    if (mbRoundToNearestPt)
+    {
+        double fInputPt = o3tl::convert(fInput, o3tl::Length::mm100, 
o3tl::Length::pt);
+        auto nInputRounded = basegfx::fround(fInputPt);
+        return o3tl::convert(double(nInputRounded), o3tl::Length::pt, 
o3tl::Length::mm100);
+    }
+    else
+    {
+        return fInput;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/editeng/source/outliner/outlin2.cxx 
b/editeng/source/outliner/outlin2.cxx
index 013c680df152..c3a672499ef5 100644
--- a/editeng/source/outliner/outlin2.cxx
+++ b/editeng/source/outliner/outlin2.cxx
@@ -482,7 +482,7 @@ void Outliner::QuickFormatDoc()
     pEditEngine->QuickFormatDoc();
 }
 
-void Outliner::SetGlobalCharStretching(double nX, double nY)
+void Outliner::setGlobalScale(double rFontX, double rFontY, double rSpacingX, 
double rSpacingY)
 {
     // reset bullet size
     sal_Int32 nParagraphs = pParaList->GetParagraphCount();
@@ -493,12 +493,18 @@ void Outliner::SetGlobalCharStretching(double nX, double 
nY)
             pPara->aBulSize.setWidth( -1 );
     }
 
-    pEditEngine->SetGlobalCharStretching( nX, nY );
+    pEditEngine->setGlobalScale(rFontX, rFontY, rSpacingX, rSpacingY);
 }
 
-void Outliner::GetGlobalCharStretching(double& rX, double& rY) const
+void Outliner::getGlobalScale(double& rFontX, double& rFontY, double& 
rSpacingX, double& rSpacingY) const
 {
-    pEditEngine->GetGlobalCharStretching(rX, rY);
+    pEditEngine->getGlobalFontScale(rFontX, rFontY);
+    pEditEngine->getGlobalSpacingScale(rSpacingX, rSpacingY);
+}
+
+void Outliner::setRoundFontSizeToPt(bool bRound) const
+{
+    pEditEngine->setRoundFontSizeToPt(bRound);
 }
 
 void Outliner::EraseVirtualDevice()
diff --git a/editeng/source/outliner/outliner.cxx 
b/editeng/source/outliner/outliner.cxx
index 72340587ba05..6cd7ab274b0a 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -48,6 +48,7 @@
 #include <sal/log.hxx>
 #include <o3tl/safeint.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/temporary.hxx>
 #include <osl/diagnose.h>
 
 #include <memory>
@@ -801,7 +802,6 @@ bool Outliner::Collapse( Paragraph const * pPara )
     return true;
 }
 
-
 vcl::Font Outliner::ImpCalcBulletFont( sal_Int32 nPara ) const
 {
     const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
@@ -840,16 +840,16 @@ vcl::Font Outliner::ImpCalcBulletFont( sal_Int32 nPara ) 
const
     }
 
     // Use original scale...
-    double nStretchX, nStretchY;
-    GetGlobalCharStretching(nStretchX, nStretchY);
+    double nStretchY = 100.0;
+    getGlobalScale(o3tl::temporary(double()), nStretchY, 
o3tl::temporary(double()), o3tl::temporary(double()));
 
-    sal_uInt16 nScale = pFmt->GetBulletRelSize() * nStretchY / 100;
-    tools::Long nScaledLineHeight = aStdFont.GetFontSize().Height();
-    nScaledLineHeight *= nScale*10;
-    nScaledLineHeight /= 1000;
+    double fScale = pFmt->GetBulletRelSize() * nStretchY / 100.0;
+    double fScaledLineHeight = aStdFont.GetFontSize().Height();
+    fScaledLineHeight *= fScale * 10;
+    fScaledLineHeight /= 1000.0;
 
     aBulletFont.SetAlignment( ALIGN_BOTTOM );
-    aBulletFont.SetFontSize( Size( 0, nScaledLineHeight ) );
+    aBulletFont.SetFontSize(Size(0, basegfx::fround(fScaledLineHeight)));
     bool bVertical = IsVertical();
     aBulletFont.SetVertical( bVertical );
     aBulletFont.SetOrientation( Degree10(bVertical ? (IsTopToBottom() ? 2700 : 
900) : 0) );
@@ -887,8 +887,11 @@ void Outliner::PaintBullet(sal_Int32 nPara, const Point& 
rStartPos, const Point&
     bool bRightToLeftPara = pEditEngine->IsRightToLeft( nPara );
 
     tools::Rectangle aBulletArea( ImpCalcBulletArea( nPara, true, false ) );
-    double nStretchX, nStretchY;
-    GetGlobalCharStretching(nStretchX, nStretchY);
+
+    double nStretchX = 100.0;
+    getGlobalScale(o3tl::temporary(double()), o3tl::temporary(double()),
+                   nStretchX, o3tl::temporary(double()));
+
     tools::Long nStretchBulletX = basegfx::fround(double(aBulletArea.Left()) * 
nStretchX / 100.0);
     tools::Long nStretchBulletWidth = 
basegfx::fround(double(aBulletArea.GetWidth()) * nStretchX / 100.0);
     aBulletArea = tools::Rectangle(Point(nStretchBulletX, aBulletArea.Top()),
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index f5487e779a4b..0693d06821f9 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -414,8 +414,12 @@ public:
     void            QuickDelete( const ESelection& rSel );
     void            QuickMarkToBeRepainted( sal_Int32 nPara );
 
-    void            SetGlobalCharStretching(double nX, double nY);
-    void            GetGlobalCharStretching(double& rX, double& rY) const;
+    void setGlobalScale(double fFontScaleX, double fFontScaleY, double 
fSpacingScaleX, double fSpacingScaleY);
+
+    void getGlobalSpacingScale(double& rX, double& rY) const;
+    void getGlobalFontScale(double& rX, double& rY) const;
+
+    void setRoundFontSizeToPt(bool bRound) const;
 
     void            SetEditTextObjectPool( SfxItemPool* pPool );
     SfxItemPool*    GetEditTextObjectPool() const;
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index a4f02568a64f..192b30d01634 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -931,8 +931,10 @@ public:
     bool            IsTextPos( const Point& rPaperPos, sal_uInt16 nBorder );
     bool            IsTextPos( const Point& rPaperPos, sal_uInt16 nBorder, 
bool* pbBulletPos );
 
-    void            SetGlobalCharStretching(double nX = 100.0, double nY = 
100.0);
-    void            GetGlobalCharStretching(double& rX, double& rY) const;
+    void setGlobalScale(double rFontX = 100.0, double rFontY = 100.0, double 
rSpacingX = 100.0, double rSpacingY = 100.0);
+    void getGlobalScale(double& rFontX, double& rFontY, double& rSpacingX, 
double& rSpacingY) const;
+    void setRoundFontSizeToPt(bool bRound) const;
+
     void            EraseVirtualDevice();
 
     bool            ShouldCreateBigTextObject() const;
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 59c9ace37113..2a72225680fb 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -315,7 +315,7 @@ public:
 
         @returns true if any paragraph properties were written
     */
-    bool WriteParagraphProperties(const css::uno::Reference< 
css::text::XTextContent >& rParagraph, const 
css::uno::Reference<css::beans::XPropertySet>& rXShapePropSet, float 
fFirstCharHeight, sal_Int32 nElement);
+    bool WriteParagraphProperties(const css::uno::Reference< 
css::text::XTextContent >& rParagraph, float fFirstCharHeight, sal_Int32 
nElement);
     void WriteParagraphNumbering(const css::uno::Reference< 
css::beans::XPropertySet >& rXPropSet, float fFirstCharHeight,
                                   sal_Int16 nLevel );
     void WriteParagraphTabStops(const 
css::uno::Reference<css::beans::XPropertySet>& rXPropSet);
diff --git a/include/svx/sdtfsitm.hxx b/include/svx/sdtfsitm.hxx
index d98e431dab68..ccdcb7c4dbe9 100644
--- a/include/svx/sdtfsitm.hxx
+++ b/include/svx/sdtfsitm.hxx
@@ -35,14 +35,17 @@ class SVXCORE_DLLPUBLIC SdrTextFitToSizeTypeItem final
 {
 public:
     static SfxPoolItem* CreateDefault();
-    SdrTextFitToSizeTypeItem(
-            css::drawing::TextFitToSizeType const eFit = 
css::drawing::TextFitToSizeType_NONE)
-        : SfxEnumItem(SDRATTR_TEXT_FITTOSIZE, eFit) {}
+    SdrTextFitToSizeTypeItem(css::drawing::TextFitToSizeType const eFit = 
css::drawing::TextFitToSizeType_NONE)
+        : SfxEnumItem(SDRATTR_TEXT_FITTOSIZE, eFit)
+    {
+    }
+
     SdrTextFitToSizeTypeItem(const SdrTextFitToSizeTypeItem& rItem)
-        : SfxEnumItem(rItem),
-        m_nMaxScale(rItem.GetMaxScale())
+        : SfxEnumItem(rItem)
+        , m_nMaxScale(rItem.GetMaxScale())
     {
     }
+
     virtual SdrTextFitToSizeTypeItem* Clone(SfxItemPool* pPool=nullptr) const 
override;
     bool operator==(const SfxPoolItem& rItem) const override;
     virtual sal_uInt16       GetValueCount() const override;
@@ -55,10 +58,11 @@ public:
     virtual bool             HasBoolValue() const override;
     virtual bool             GetBoolValue() const override;
     virtual void             SetBoolValue(bool bVal) override;
-    void SetMaxScale(sal_Int16 nMaxScale) { m_nMaxScale = nMaxScale; }
-    sal_Int16 GetMaxScale() const { return m_nMaxScale; }
+
+    void SetMaxScale(double nMaxScale) { m_nMaxScale = nMaxScale; }
+    double GetMaxScale() const { return m_nMaxScale; }
 private:
-    sal_Int16 m_nMaxScale = 0;
+    double m_nMaxScale = 0.0;
 };
 
 #endif
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index a1cccb0804a4..ccecae20e2f8 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -275,6 +275,8 @@ private:
                                        Fraction&        aFitXCorrection ) 
const;
     void ImpAutoFitText( SdrOutliner& rOutliner ) const;
     void ImpAutoFitText( SdrOutliner& rOutliner, const Size& rShapeSize, bool 
bIsVerticalWriting ) const;
+    void autoFitTextForCompatibility(SdrOutliner& rOutliner, const Size& 
rShapeSize) const;
+
     SVX_DLLPRIVATE rtl::Reference<SdrObject> 
ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const;
     SVX_DLLPRIVATE void ImpRegisterLink();
     SVX_DLLPRIVATE void ImpDeregisterLink();
@@ -403,7 +405,9 @@ public:
     // FitToSize and Fontwork are not taken into account in GetTextSize()!
     virtual const Size& GetTextSize() const;
     void FitFrameToTextSize();
-    sal_uInt16 GetFontScaleY() const;
+
+    double GetFontScale() const;
+    double GetSpacingScale() const;
 
     // Simultaneously sets the text into the Outliner (possibly
     // the one of the EditOutliner) and sets the PaperSize.
diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx
index 70be33007013..8a6302659702 100644
--- a/include/svx/unoshprp.hxx
+++ b/include/svx/unoshprp.hxx
@@ -363,7 +363,7 @@
     { UNO_NAME_MISC_OBJ_SIZEPROTECT,  SDRATTR_OBJSIZEPROTECT          , 
cppu::UnoType<bool>::get(),                      0,  0},\
     { u"UINameSingular",               OWN_ATTR_UINAME_SINGULAR        , 
::cppu::UnoType<OUString>::get(),    css::beans::PropertyAttribute::READONLY,   
0}, \
     { u"UINamePlural",                 OWN_ATTR_UINAME_PLURAL          , 
::cppu::UnoType<OUString>::get(),    css::beans::PropertyAttribute::READONLY,   
0}, \
-    { u"TextFitToSizeScale", OWN_ATTR_TEXTFITTOSIZESCALE, 
::cppu::UnoType<sal_Int16>::get(), 0, 0}, \
+    { u"TextFitToSizeScale", OWN_ATTR_TEXTFITTOSIZESCALE, 
::cppu::UnoType<double>::get(), 0, 0}, \
     /* #i68101# */ \
     { UNO_NAME_MISC_OBJ_TITLE,        OWN_ATTR_MISC_OBJ_TITLE         , 
::cppu::UnoType<OUString>::get(),    0,  0}, \
     { UNO_NAME_MISC_OBJ_DESCRIPTION,  OWN_ATTR_MISC_OBJ_DESCRIPTION   , 
::cppu::UnoType<OUString>::get(),    0,  0}, \
diff --git a/oox/inc/drawingml/textparagraph.hxx 
b/oox/inc/drawingml/textparagraph.hxx
index 4920c99da7c5..1f43249372a5 100644
--- a/oox/inc/drawingml/textparagraph.hxx
+++ b/oox/inc/drawingml/textparagraph.hxx
@@ -77,8 +77,7 @@ public:
                                     const TextListStyle& rMasterTextListStyle,
                                     const TextListStyle& rTextListStyle,
                                     bool bFirst,
-                                    float nDefaultCharHeight,
-                                    sal_Int32 nAutofitFontScale) const;
+                                    float nDefaultCharHeight) const;
 
     bool HasMathXml() const
     {
diff --git a/oox/inc/drawingml/textparagraphproperties.hxx 
b/oox/inc/drawingml/textparagraphproperties.hxx
index d3742e7377e0..e362119ed6f9 100644
--- a/oox/inc/drawingml/textparagraphproperties.hxx
+++ b/oox/inc/drawingml/textparagraphproperties.hxx
@@ -104,7 +104,6 @@ public:
                                                 const BulletList* 
pMasterBuList,
                                                 bool bApplyBulletList,
                                                 float fFontSize,
-                                                sal_Int32 nAutofitFontScale = 
100000,
                                                 bool bPushDefaultValues = 
false ) const;
 
     /** Returns the largest character size of this paragraph. If possible the
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index efba958fa0e4..7927b7aa6945 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -186,13 +186,13 @@ void Diagram::syncDiagramFontHeights()
     {
         // Find out the minimum scale within this group.
         const ShapePairs& rShapePairs = rNameAndPairs.second;
-        sal_Int16 nMinScale = 100;
+        double nMinScale = 100.0;
         for (const auto& rShapePair : rShapePairs)
         {
             uno::Reference<beans::XPropertySet> 
xPropertySet(rShapePair.second, uno::UNO_QUERY);
             if (xPropertySet.is())
             {
-                sal_Int16 nTextFitToSizeScale = 0;
+                double nTextFitToSizeScale = 0.0;
                 xPropertySet->getPropertyValue("TextFitToSizeScale") >>= 
nTextFitToSizeScale;
                 if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale)
                 {
@@ -202,7 +202,7 @@ void Diagram::syncDiagramFontHeights()
         }
 
         // Set that minimum scale for all members of the group.
-        if (nMinScale < 100)
+        if (nMinScale < 100.0)
         {
             for (const auto& rShapePair : rShapePairs)
             {
diff --git a/oox/source/drawingml/textbody.cxx 
b/oox/source/drawingml/textbody.cxx
index 1be15c4f885d..266ff44b22f9 100644
--- a/oox/source/drawingml/textbody.cxx
+++ b/oox/source/drawingml/textbody.cxx
@@ -65,7 +65,7 @@ void TextBody::insertAt(
     for (auto const& paragraph : maParagraphs)
     {
         paragraph->insertAt(rFilterBase, xText, xAt, rTextStyleProperties, 
aMasterTextStyle,
-                            maTextListStyle, (nIndex == 0), nCharHeight, 
getTextProperties().mnFontScale);
+                            maTextListStyle, (nIndex == 0), nCharHeight);
         ++nIndex;
     }
 }
@@ -149,7 +149,7 @@ void TextBody::ApplyStyleEmpty(
         TextParagraphProperties aParaProp;
         aParaProp.apply(*pTextParagraphStyle);
         aParaProp.pushToPropSet(&rFilterBase, xProps, aioBulletList, 
&pTextParagraphStyle->getBulletList(),
-                                true, nCharHeight, 
getTextProperties().mnFontScale, true);
+                                true, nCharHeight, true);
     }
 }
 
diff --git a/oox/source/drawingml/textparagraph.cxx 
b/oox/source/drawingml/textparagraph.cxx
index f08efdbff3c3..e33cbb690ee9 100644
--- a/oox/source/drawingml/textparagraph.cxx
+++ b/oox/source/drawingml/textparagraph.cxx
@@ -88,7 +88,7 @@ void TextParagraph::insertAt(
         const TextCharacterProperties& rTextStyleProperties,
         const TextListStyle& rMasterTextListStyle,
         const TextListStyle& rTextListStyle, bool bFirst,
-        float nDefaultCharHeight, sal_Int32 nAutofitFontScale) const
+        float nDefaultCharHeight) const
 {
     try {
         sal_Int32 nParagraphSize = 0;
@@ -176,7 +176,7 @@ void TextParagraph::insertAt(
             }
 
             float fCharacterSize = nCharHeight > 0 ? GetFontHeight ( 
nCharHeight ) : pTextParagraphStyle->getCharHeightPoints( 12 );
-            aParaProp.pushToPropSet( &rFilterBase, xProps, aioBulletList, 
&pTextParagraphStyle->getBulletList(), true, fCharacterSize, nAutofitFontScale, 
true );
+            aParaProp.pushToPropSet( &rFilterBase, xProps, aioBulletList, 
&pTextParagraphStyle->getBulletList(), true, fCharacterSize, true );
         }
 
         // empty paragraphs do not have bullets in ppt
diff --git a/oox/source/drawingml/textparagraphproperties.cxx 
b/oox/source/drawingml/textparagraphproperties.cxx
index af65e0037d16..8122c4e53324 100644
--- a/oox/source/drawingml/textparagraphproperties.cxx
+++ b/oox/source/drawingml/textparagraphproperties.cxx
@@ -407,7 +407,7 @@ void TextParagraphProperties::apply( const 
TextParagraphProperties& rSourceProps
 
 void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* 
pFilterBase,
     const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, 
const BulletList* pMasterBuList, bool bApplyBulletMap, float fCharacterSize,
-    sal_Int32 nAutofitFontScale, bool bPushDefaultValues ) const
+    bool bPushDefaultValues ) const
 {
     PropertySet aPropSet( xPropSet );
     aPropSet.setProperties( maTextParagraphPropertyMap );
@@ -433,14 +433,6 @@ void TextParagraphProperties::pushToPropSet( const 
::oox::core::XmlFilterBase* p
     std::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
     std::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation 
);
 
-    // tdf#149961 Impress scales the indents when text is autofitted while 
Powerpoint doesn't
-    // Try to counteract this by multiplying indents by the inverse of the 
autofit font scale.
-    if ( nAutofitFontScale )
-    {
-        if ( noParaLeftMargin ) noParaLeftMargin = *noParaLeftMargin * 
MAX_PERCENT / nAutofitFontScale;
-        if ( noFirstLineIndentation ) noFirstLineIndentation = 
*noFirstLineIndentation * MAX_PERCENT / nAutofitFontScale;
-    }
-
     if ( nNumberingType != NumberingType::NUMBER_NONE )
     {
         if ( noParaLeftMargin )
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 5335dca58486..d610435d0eb2 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3200,7 +3200,7 @@ void DrawingML::WriteLinespacing(const LineSpacing& 
rSpacing, float fFirstCharHe
     }
 }
 
-bool DrawingML::WriteParagraphProperties(const Reference<XTextContent>& 
rParagraph, const Reference<XPropertySet>& rXShapePropSet, float 
fFirstCharHeight, sal_Int32 nElement)
+bool DrawingML::WriteParagraphProperties(const Reference<XTextContent>& 
rParagraph, float fFirstCharHeight, sal_Int32 nElement)
 {
     Reference< XPropertySet > rXPropSet( rParagraph, UNO_QUERY );
     Reference< XPropertyState > rXPropState( rParagraph, UNO_QUERY );
@@ -3294,24 +3294,6 @@ bool DrawingML::WriteParagraphProperties(const 
Reference<XTextContent>& rParagra
     if (GetProperty(rXPropSet, "ParaTabStopDefaultDistance"))
         mAny >>= nParaDefaultTabSize;
 
-    // for autofitted textboxes, scale the indents
-    if (GetProperty(rXShapePropSet, "TextFitToSize") && 
mAny.get<TextFitToSizeType>() == TextFitToSizeType_AUTOFIT)
-    {
-        SvxShapeText* pTextShape = 
dynamic_cast<SvxShapeText*>(rXShapePropSet.get());
-        if (pTextShape)
-        {
-            SdrTextObj* pTextObject = 
DynCastSdrTextObj(pTextShape->GetSdrObject());
-            if (pTextObject)
-            {
-                const auto nFontScaleY = pTextObject->GetFontScaleY();
-                nLeftMargin = nLeftMargin * nFontScaleY / 100;
-                nLineIndentation = nLineIndentation * nFontScaleY / 100;
-                nParaLeftMargin = nParaLeftMargin * nFontScaleY / 100;
-                nParaFirstLineIndent = nParaFirstLineIndent * nFontScaleY / 
100;
-            }
-        }
-    }
-
     if (nParaLeftMargin) // For Paragraph
         mpFS->startElementNS( XML_a, nElement,
                            XML_lvl, 
sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0),
@@ -3401,7 +3383,7 @@ void DrawingML::WriteLstStyles(const 
css::uno::Reference<css::text::XTextContent
             fFirstCharHeight = 
xFirstRunPropSet->getPropertyValue("CharHeight").get<float>();
 
         mpFS->startElementNS(XML_a, XML_lstStyle);
-        if( !WriteParagraphProperties(rParagraph, rXShapePropSet, 
fFirstCharHeight, XML_lvl1pPr) )
+        if( !WriteParagraphProperties(rParagraph, fFirstCharHeight, 
XML_lvl1pPr) )
             mpFS->startElementNS(XML_a, XML_lvl1pPr);
         WriteRunProperties(xFirstRunPropSet, false, XML_defRPr, true, 
rbOverridingCharHeight,
                            rnCharHeight, GetScriptType(rRun->getString()), 
rXShapePropSet);
@@ -3443,7 +3425,7 @@ void DrawingML::WriteParagraph( const Reference< 
XTextContent >& rParagraph,
                     rnCharHeight = 100 * fFirstCharHeight;
                     rbOverridingCharHeight = true;
                 }
-                WriteParagraphProperties(rParagraph, rXShapePropSet, 
fFirstCharHeight, XML_pPr);
+                WriteParagraphProperties(rParagraph, fFirstCharHeight, 
XML_pPr);
                 bPropertiesWritten = true;
             }
             WriteRun( run, rbOverridingCharHeight, rnCharHeight, 
rXShapePropSet);
@@ -3994,16 +3976,29 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
             {
                 const sal_Int32 MAX_SCALE_VAL = 100000;
                 sal_Int32 nFontScale = MAX_SCALE_VAL;
+                sal_Int32 nSpacingReduction = 0;
                 SvxShapeText* pTextShape = 
dynamic_cast<SvxShapeText*>(rXIface.get());
                 if (pTextShape)
                 {
                     SdrTextObj* pTextObject = 
DynCastSdrTextObj(pTextShape->GetSdrObject());
                     if (pTextObject)
-                        nFontScale = pTextObject->GetFontScaleY() * 1000;
+                    {
+                        nFontScale = sal_Int32(pTextObject->GetFontScale() * 
1000.0);
+                        nSpacingReduction = sal_Int32((100.0 - 
pTextObject->GetSpacingScale()) * 1000.0);
+                    }
                 }
 
-                mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale,
-                    sax_fastparser::UseIf(OString::number(nFontScale), 
nFontScale < MAX_SCALE_VAL && nFontScale > 0));
+                bool bExportFontScale = false;
+                if (nFontScale < MAX_SCALE_VAL && nFontScale > 0)
+                    bExportFontScale = true;
+
+                bool bExportSpaceReduction = false;
+                if (nSpacingReduction < MAX_SCALE_VAL && nSpacingReduction > 0)
+                    bExportSpaceReduction = true;
+
+                mpFS->singleElementNS(XML_a, XML_normAutofit,
+                    XML_fontScale, 
sax_fastparser::UseIf(OString::number(nFontScale), bExportFontScale),
+                    XML_lnSpcReduction, 
sax_fastparser::UseIf(OString::number(nSpacingReduction), 
bExportSpaceReduction));
             }
             else
             {
@@ -4091,7 +4086,7 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
         if( aAny >>= xParagraph )
         {
             mpFS->startElementNS(XML_a, XML_p);
-            WriteParagraphProperties(xParagraph, rXPropSet, nCharHeight, 
XML_pPr);
+            WriteParagraphProperties(xParagraph, nCharHeight, XML_pPr);
             sal_Int16 nDummy = -1;
             WriteRunProperties(rXPropSet, false, XML_endParaRPr, false,
                                bOverridingCharHeight, nCharHeight, nDummy, 
rXPropSet);
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index b4d993a3c0c9..7d04d29886ec 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -1823,10 +1823,10 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, 
testTextColumns_3columns)
         CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(300)),
                              xColProps->getPropertyValue("AutomaticDistance"));
         // Scale value may be unstable; just test that the text is actually 
scaled
-        sal_Int16 nScale;
-        CPPUNIT_ASSERT(xProps->getPropertyValue("TextFitToSizeScale") >>= 
nScale);
-        CPPUNIT_ASSERT_GREATER(sal_Int16(0), nScale);
-        CPPUNIT_ASSERT_LESS(sal_Int16(100), nScale);
+        double fScale;
+        CPPUNIT_ASSERT(xProps->getPropertyValue("TextFitToSizeScale") >>= 
fScale);
+        CPPUNIT_ASSERT_GREATER(0.0, fScale);
+        CPPUNIT_ASSERT_LESS(100.0, fScale);
     }
 
     save("Impress Office Open XML");
@@ -1843,10 +1843,10 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, 
testTextColumns_3columns)
         CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(300)),
                              xColProps->getPropertyValue("AutomaticDistance"));
         // Scale value may be unstable; just test that the text is actually 
scaled
-        sal_Int16 nScale;
-        CPPUNIT_ASSERT(xProps->getPropertyValue("TextFitToSizeScale") >>= 
nScale);
-        CPPUNIT_ASSERT_GREATER(sal_Int16(0), nScale);
-        CPPUNIT_ASSERT_LESS(sal_Int16(100), nScale);
+        double fScale;
+        CPPUNIT_ASSERT(xProps->getPropertyValue("TextFitToSizeScale") >>= 
fScale);
+        CPPUNIT_ASSERT_GREATER(0.0, fScale);
+        CPPUNIT_ASSERT_LESS(100.0, fScale);
     }
 
     xmlDocUniquePtr pXmlDocRels = parseExport("ppt/slides/slide1.xml");
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx 
b/sd/qa/unit/export-tests-ooxml3.cxx
index ccbfc6e35335..3931c53b912b 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -233,7 +233,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testFontScale)
     // Rounding errors possible, approximate value (+/- 1%)
     OUString sScale = getXPath(
         pXmlDocContent, 
"/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale");
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(76000), sScale.toInt32(), 1000);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(81111), sScale.toInt32(), 1000);
 }
 
 CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testShapeAutofitPPTX)
@@ -1914,15 +1914,12 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, 
testAutofittedTextboxIndent)
 
     save("Impress Office Open XML");
 
-    // Without the accompanying fix in place, these tests would have failed 
with:
-    // - Expected: 691200
-    // - Actual  : 1080000
-    // i.e. paragraph indent wasn't scaled proportionally to autofitted textbox
-    // font scale on export
+    // Check that the indent hasn't changed and wasn't scaled when exporting
+    // (the behaviour changed).
 
     xmlDocUniquePtr pXmlDocContent1 = parseExport("ppt/slides/slide1.xml");
     assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p[1]/a:pPr", "marL",
-                "712800");
+                "1080000");
 }
 
 CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf151622_oleIcon)
diff --git a/sd/qa/unit/import-tests-smartart.cxx 
b/sd/qa/unit/import-tests-smartart.cxx
index 895ca7f03211..049a64eb0193 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -1528,13 +1528,13 @@ CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, 
testAutofitSync)
     uno::Reference<drawing::XShape> xMiddle = getChildShape(xDiagram, 2);
     uno::Reference<beans::XPropertySet> 
xFirstInner(getChildShape(getChildShape(xMiddle, 0), 0),
                                                     uno::UNO_QUERY);
-    sal_Int16 nFirstScale = 0;
+    double nFirstScale = 0;
     CPPUNIT_ASSERT(xFirstInner->getPropertyValue("TextFitToSizeScale") >>= 
nFirstScale);
-    CPPUNIT_ASSERT_GREATER(static_cast<sal_Int16>(0), nFirstScale);
-    CPPUNIT_ASSERT_LESS(static_cast<sal_Int16>(100), nFirstScale);
+    CPPUNIT_ASSERT_GREATER(0.0, nFirstScale);
+    CPPUNIT_ASSERT_LESS(100.0, nFirstScale);
     uno::Reference<beans::XPropertySet> 
xSecondInner(getChildShape(getChildShape(xMiddle, 2), 0),
                                                      uno::UNO_QUERY);
-    sal_Int16 nSecondScale = 0;
+    double nSecondScale = 0;
     CPPUNIT_ASSERT(xSecondInner->getPropertyValue("TextFitToSizeScale") >>= 
nSecondScale);
 
     // Without the accompanying fix in place, this test would have failed with:
diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx
index 9d44f11552d8..e585673e3ad8 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -1343,8 +1343,10 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf120028)
     double fCharHeight = 0;
     xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
     CPPUNIT_ASSERT_DOUBLES_EQUAL(13.5, fCharHeight, 1E-12);
-    // 13.5 * 90% is approx. 12.1 (the correct scaled font size)
-    CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int16(90)), 
xShape->getPropertyValue("TextFitToSizeScale"));
+
+    double fTextSclale = 0.0;
+    xShape->getPropertyValue("TextFitToSizeScale") >>= fTextSclale;
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(92.0, fTextSclale, 1E1);
 }
 
 CPPUNIT_TEST_FIXTURE(SdImportTest2, testDescriptionImport)
@@ -1845,11 +1847,9 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, 
testTdf149961AutofitIndentation)
         const SvxNumBulletItem* pNumFmt = 
aEdit.GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
         CPPUNIT_ASSERT(pNumFmt);
 
-        // Without the accompanying fix in place, this test would have failed 
with:
-        // - Expected: 12700
-        // - Actual  : 3175
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(12700), 
pNumFmt->GetNumRule().GetLevel(0).GetAbsLSpace());
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(-12700),
+        // Spacing doesn't change when it is scaled
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(3175), 
pNumFmt->GetNumRule().GetLevel(0).GetAbsLSpace());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(-3175),
                              
pNumFmt->GetNumRule().GetLevel(0).GetFirstLineOffset());
     }
 }
diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx
index d8503d0412f7..a7204b992ed8 100644
--- a/sd/source/ui/view/drtxtob.cxx
+++ b/sd/source/ui/view/drtxtob.cxx
@@ -46,6 +46,7 @@
 #include <editeng/writingmodeitem.hxx>
 #include <editeng/frmdiritem.hxx>
 #include <editeng/fhgtitem.hxx>
+#include <o3tl/temporary.hxx>
 
 #include <sfx2/objface.hxx>
 
@@ -165,7 +166,7 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet )
             case SID_ATTR_CHAR_STRIKEOUT:
             case SID_ATTR_CHAR_CASEMAP:
             {
-                double stretchX = 100.0;
+                double stretchY = 100.0;
                 SvxScriptSetItem aSetItem( nSlotId, GetPool() );
                 aSetItem.GetItemSet().Put( aAttrSet, false );
 
@@ -183,9 +184,8 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet )
                     if (OutlineView* pOView = 
dynamic_cast<OutlineView*>(mpView))
                         pOLV = 
pOView->GetViewByWindow(mpViewShell->GetActiveWindow());
 
-                    double stretchY = 100.0;
-                    if( pOutliner )
-                        pOutliner->GetGlobalCharStretching(stretchX, stretchY);
+                    if (pOutliner)
+                        pOutliner->getGlobalScale(o3tl::temporary(double()), 
stretchY, o3tl::temporary(double()), o3tl::temporary(double()));
 
                     if(pOLV && !pOLV->GetSelection().HasRange())
                     {
@@ -204,7 +204,7 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet )
                     if( nSlotId == SID_ATTR_CHAR_FONTHEIGHT )
                     {
                         SvxFontHeightItem aFontItem = dynamic_cast<const 
SvxFontHeightItem&>(*pI);
-                        aFontItem.SetHeight(aFontItem.GetHeight(), stretchX, 
aFontItem.GetPropUnit());
+                        aFontItem.SetHeight(aFontItem.GetHeight() * (stretchY 
/ 100.0), 100, aFontItem.GetPropUnit());
                         aFontItem.SetWhich(nWhich);
                         aAttrSet.Put( aFontItem );
                     }
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 20e54ca976ac..65f1dab7db65 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -43,6 +43,7 @@
 #include <svx/sdtfsitm.hxx>
 #include <svx/sdtmfitm.hxx>
 #include <svx/xtextit0.hxx>
+#include <svx/compatflags.hxx>
 #include <sdr/properties/textproperties.hxx>
 #include <sdr/contact/viewcontactoftextobj.hxx>
 #include <basegfx/tuple/b2dtuple.hxx>
@@ -51,8 +52,11 @@
 #include <vcl/virdev.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <sal/log.hxx>
+#include <o3tl/unit_conversion.hxx>
 #include <o3tl/temporary.hxx>
 #include <unotools/configmgr.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
 
 using namespace com::sun::star;
 
@@ -908,6 +912,9 @@ void SdrTextObj::ImpSetCharStretching(SdrOutliner& 
rOutliner, const Size& rTextS
         }
 #endif
     }
+
+    rOutliner.setRoundFontSizeToPt(false);
+
     unsigned nLoopCount=0;
     bool bNoMoreLoop = false;
     tools::Long nXDiff0=0x7FFFFFFF;
@@ -982,7 +989,7 @@ void SdrTextObj::ImpSetCharStretching(SdrOutliner& 
rOutliner, const Size& rTextS
             nY = nX;
             bNoMoreLoop = true;
         }
-        rOutliner.SetGlobalCharStretching(nX, nY);
+        rOutliner.setGlobalScale(nX, nY);
         nLoopCount++;
         Size aSiz(rOutliner.CalcTextSize());
         tools::Long nXDiff = aSiz.Width() - nWantWdt;
@@ -1172,7 +1179,8 @@ void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl 
) const
         nOutlinerMode = OutlinerMode::TextObject;
     rOutl.Init( nOutlinerMode );
 
-    rOutl.SetGlobalCharStretching(100.0, 100.0);
+    rOutl.setGlobalScale(100.0, 100.0, 100.0, 100.0);
+
     EEControlBits nStat=rOutl.GetControlWord();
     nStat &= 
~EEControlBits(EEControlBits::STRETCHING|EEControlBits::AUTOPAGESIZE);
     rOutl.SetControlWord(nStat);
@@ -1230,15 +1238,26 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool     
        bContourFrame,
     }
 }
 
-sal_uInt16 SdrTextObj::GetFontScaleY() const
+double SdrTextObj::GetFontScale() const
 {
     SdrOutliner& rOutliner = ImpGetDrawOutliner();
     // This eventually calls ImpAutoFitText
     UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle()));
 
-    double nStretchY;
-    rOutliner.GetGlobalCharStretching(o3tl::temporary(double()), nStretchY);
-    return nStretchY;
+    double fScaleY;
+    rOutliner.getGlobalScale(o3tl::temporary(double()), fScaleY, 
o3tl::temporary(double()), o3tl::temporary(double()));
+    return fScaleY;
+}
+
+double SdrTextObj::GetSpacingScale() const
+{
+    SdrOutliner& rOutliner = ImpGetDrawOutliner();
+    // This eventually calls ImpAutoFitText
+    UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle()));
+
+    double fSpacingScaleY;
+    rOutliner.getGlobalScale(o3tl::temporary(double()), 
o3tl::temporary(double()), o3tl::temporary(double()), fSpacingScaleY);
+    return fSpacingScaleY;
 }
 
 void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const
@@ -1253,6 +1272,12 @@ void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner 
) const
 void SdrTextObj::ImpAutoFitText(SdrOutliner& rOutliner, const Size& rTextSize,
                                 bool bIsVerticalWriting) const
 {
+    if (!bIsVerticalWriting)
+    {
+        autoFitTextForCompatibility(rOutliner, rTextSize);
+        return;
+    }
+
     // EditEngine formatting is unstable enough for
     // line-breaking text that we need some more samples
 
@@ -1260,6 +1285,7 @@ void SdrTextObj::ImpAutoFitText(SdrOutliner& rOutliner, 
const Size& rTextSize,
     double nMinStretchX = 0.0;
     double nMinStretchY = 0.0;
     std::array<sal_Int32, 10> aOldStretchXVals = {0,0,0,0,0,0,0,0,0,0};
+    rOutliner.setRoundFontSizeToPt(false);
     for (size_t i = 0; i < aOldStretchXVals.size(); ++i)
     {
         const Size aCurrTextSize = rOutliner.CalcTextSizeNTP();
@@ -1283,7 +1309,7 @@ void SdrTextObj::ImpAutoFitText(SdrOutliner& rOutliner, 
const Size& rTextSize,
         fFactor = std::sqrt(fFactor);
 
         double nCurrStretchX, nCurrStretchY;
-        rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY);
+        rOutliner.getGlobalScale(nCurrStretchX, nCurrStretchY, 
o3tl::temporary(double()), o3tl::temporary(double()));
 
         if (fFactor >= 0.98)
         {
@@ -1302,20 +1328,107 @@ void SdrTextObj::ImpAutoFitText(SdrOutliner& 
rOutliner, const Size& rTextSize,
             nCurrStretchX = double(basegfx::fround(nCurrStretchX * fFactor * 
100.0)) / 100.00;
             nCurrStretchY = double(basegfx::fround(nCurrStretchY * fFactor * 
100.0)) / 100.00;
 
-            rOutliner.SetGlobalCharStretching(std::min(100.0, nCurrStretchX), 
std::min(100.0, nCurrStretchY));
+            double nStretchX = std::min(100.0, nCurrStretchX);
+            double nStretchY = std::min(100.0, nCurrStretchY);
+
+            rOutliner.setGlobalScale(nStretchX, nStretchY, nStretchX, 
nStretchY);
             SAL_INFO("svx", "zoom is " << nCurrStretchX);
         }
     }
 
     const SdrTextFitToSizeTypeItem& rItem = 
GetObjectItem(SDRATTR_TEXT_FITTOSIZE);
-    if (rItem.GetMaxScale() > 0)
+    if (rItem.GetMaxScale() > 0.0)
     {
-        nMinStretchX = std::min<sal_uInt16>(rItem.GetMaxScale(), nMinStretchX);
-        nMinStretchY = std::min<sal_uInt16>(rItem.GetMaxScale(), nMinStretchY);
+        nMinStretchX = std::min(rItem.GetMaxScale(), nMinStretchX);
+        nMinStretchY = std::min(rItem.GetMaxScale(), nMinStretchY);
     }
 
     SAL_INFO("svx", "final zoom is " << nMinStretchX);
-    rOutliner.SetGlobalCharStretching(std::min(100.0, nMinStretchX), 
std::min(100.0, nMinStretchY));
+
+    nMinStretchX = std::min(100.0, nMinStretchX);
+    nMinStretchY = std::min(100.0, nMinStretchY);
+
+    rOutliner.setGlobalScale(nMinStretchX, nMinStretchY, nMinStretchX, 
nMinStretchY);
+}
+
+void SdrTextObj::autoFitTextForCompatibility(SdrOutliner& rOutliner, const 
Size& rTextBoxSize) const
+{
+    rOutliner.setRoundFontSizeToPt(true);
+
+    const SdrTextFitToSizeTypeItem& rItem = 
GetObjectItem(SDRATTR_TEXT_FITTOSIZE);
+    double fMaxScale = rItem.GetMaxScale();
+    if (fMaxScale > 0.0)
+    {
+        rOutliner.setGlobalScale(fMaxScale, fMaxScale, 100.0, 100.0);
+    }
+    else
+    {
+        fMaxScale = 100.0;
+    }
+
+    Size aCurrentTextBoxSize = rOutliner.CalcTextSizeNTP();
+    tools::Long nExtendTextBoxBy = -50;
+    aCurrentTextBoxSize.extendBy(0, nExtendTextBoxBy);
+    double fCurrentFitFactor = double(rTextBoxSize.Height()) / 
aCurrentTextBoxSize.Height();
+
+    if (fCurrentFitFactor >= 1.0)
+        return;
+
+    sal_Int32 nFontHeight = 
GetObjectItemSet().Get(EE_CHAR_FONTHEIGHT).GetHeight();
+
+    double fFontHeightPt = o3tl::convert(double(nFontHeight), 
o3tl::Length::mm100, o3tl::Length::pt);
+    double fMinY = 0.0;
+    double fMaxY = fMaxScale;
+
+    double fBestFontScale = 0.0;
+    double fBestSpacing = fMaxScale;
+    double fBestFitFactor = fCurrentFitFactor;
+
+    double fInTheMidle = 0.5;
+
+    int iteration = 0;
+    double fFitFactorTarget = 1.00;
+
+    while (iteration < 10)
+    {
+        iteration++;
+        double fScaleY = fMinY + (fMaxY - fMinY) * fInTheMidle;
+
+        double fScaledFontHeight = fFontHeightPt * (fScaleY / 100.0);
+        double fRoundedScaledFontHeight = std::floor(fScaledFontHeight * 10.0) 
/ 10.0;
+        double fCurrentFontScale = (fRoundedScaledFontHeight / fFontHeightPt) 
* 100.0;
+
+        fCurrentFitFactor = 0.0; // reset fit factor;
+
+        for (double fCurrentSpacing : {100.0, 90.0, 80.0})
+        {
+            if (fCurrentFitFactor >= fFitFactorTarget)
+                continue;
+
+            rOutliner.setGlobalScale(fCurrentFontScale, fCurrentFontScale, 
100.0, fCurrentSpacing);
+
+            aCurrentTextBoxSize = rOutliner.CalcTextSizeNTP();
+            aCurrentTextBoxSize.extendBy(0, nExtendTextBoxBy);
+            fCurrentFitFactor = double(rTextBoxSize.Height()) / 
aCurrentTextBoxSize.Height();
+
+            if (fCurrentSpacing == 100.0)
+            {
+                if (fCurrentFitFactor > fFitFactorTarget)
+                    fMinY = fCurrentFontScale;
+                else
+                    fMaxY = fCurrentFontScale;
+            }
+
+            if ((fBestFitFactor < fFitFactorTarget && fCurrentFitFactor > 
fBestFitFactor)
+            ||  (fCurrentFitFactor >= fFitFactorTarget && fCurrentFitFactor < 
fBestFitFactor))
+            {
+                fBestFontScale = fCurrentFontScale;
+                fBestSpacing = fCurrentSpacing;
+                fBestFitFactor = fCurrentFitFactor;
+            }
+        }
+    }
+    rOutliner.setGlobalScale(fBestFontScale, fBestFontScale, 100.0, 
fBestSpacing);
 }
 
 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, 
tools::Rectangle& rPaintRect ) const
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx 
b/svx/source/svdraw/svdotextdecomposition.cxx
index ad6edb104e01..ddbc6bfe540a 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -1226,7 +1226,7 @@ void SdrTextObj::impDecomposeStretchTextPrimitive(
     // to layout without mirroring
     const double fScaleX(fabs(aScale.getX()) / aOutlinerScale.getX());
     const double fScaleY(fabs(aScale.getY()) / aOutlinerScale.getY());
-    rOutliner.SetGlobalCharStretching(fScaleX * 100.0, fScaleY * 100.0);
+    rOutliner.setGlobalScale(fScaleX * 100.0, fScaleY * 100.0, 100.0, 100.0);
 
     // When mirroring in X and Y,
     // move the null point which was top left to bottom right.
diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx
index 5e89f5d42874..94f73bfbf206 100644
--- a/svx/source/svdraw/svdoutl.cxx
+++ b/svx/source/svdraw/svdoutl.cxx
@@ -50,7 +50,7 @@ void SdrOutliner::SetTextObj( const SdrTextObj* pObj )
             nOutlinerMode2 = OutlinerMode::TextObject;
         Init( nOutlinerMode2 );
 
-        SetGlobalCharStretching();
+        setGlobalScale(100.0, 100.0, 100.0, 100.0);
 
         EEControlBits nStat = GetControlWord();
         nStat &= ~EEControlBits( EEControlBits::STRETCHING | 
EEControlBits::AUTOPAGESIZE );
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index 4ee178c5e58a..85cd6045a234 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -173,7 +173,7 @@ protected:
 };
 
 /// Calculates what scaling factor will be used for autofit text scaling of 
this shape.
-sal_Int16 GetTextFitToSizeScale(SdrObject* pObject)
+double GetTextFitToSizeScale(SdrObject* pObject)
 {
     SdrTextObj* pTextObj = DynCastSdrTextObj(pObject);
     if (!pTextObj)
@@ -188,7 +188,7 @@ sal_Int16 GetTextFitToSizeScale(SdrObject* pObject)
         return 0;
     }
 
-    return pTextObj->GetFontScaleY();
+    return pTextObj->GetFontScale();
 }
 }
 
@@ -2361,7 +2361,7 @@ bool SvxShape::setPropertyValueImpl( const OUString&, 
const SfxItemPropertyMapEn
 
     case OWN_ATTR_TEXTFITTOSIZESCALE:
     {
-        sal_Int16 nMaxScale = 0;
+        double nMaxScale = 0.0;
         if (rValue >>= nMaxScale)
         {
             SdrTextFitToSizeTypeItem 
aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE));
@@ -2871,7 +2871,8 @@ bool SvxShape::getPropertyValueImpl( const OUString&, 
const SfxItemPropertyMapEn
 
     case OWN_ATTR_TEXTFITTOSIZESCALE:
     {
-        rValue <<= GetTextFitToSizeScale(GetSdrObject());
+        double nScale = GetTextFitToSizeScale(GetSdrObject());
+        rValue <<= nScale;
         break;
     }
 

Reply via email to