summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/source/editeng/editeng.cxx23
-rw-r--r--editeng/source/editeng/editobj.cxx11
-rw-r--r--editeng/source/editeng/editobj2.hxx14
-rw-r--r--editeng/source/editeng/impedit.hxx98
-rw-r--r--editeng/source/editeng/impedit2.cxx29
-rw-r--r--editeng/source/editeng/impedit3.cxx148
-rw-r--r--editeng/source/editeng/impedit4.cxx24
-rw-r--r--editeng/source/outliner/outlin2.cxx14
-rw-r--r--editeng/source/outliner/outliner.cxx23
-rw-r--r--include/editeng/editeng.hxx8
-rw-r--r--include/editeng/outliner.hxx6
-rw-r--r--include/oox/export/drawingml.hxx2
-rw-r--r--include/svx/sdtfsitm.hxx20
-rw-r--r--include/svx/svdotext.hxx6
-rw-r--r--include/svx/unoshprp.hxx2
-rw-r--r--oox/inc/drawingml/textparagraph.hxx3
-rw-r--r--oox/inc/drawingml/textparagraphproperties.hxx1
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx6
-rw-r--r--oox/source/drawingml/textbody.cxx4
-rw-r--r--oox/source/drawingml/textparagraph.cxx4
-rw-r--r--oox/source/drawingml/textparagraphproperties.cxx10
-rw-r--r--oox/source/export/drawingml.cxx45
-rw-r--r--sd/qa/unit/export-tests-ooxml2.cxx16
-rw-r--r--sd/qa/unit/export-tests-ooxml3.cxx11
-rw-r--r--sd/qa/unit/import-tests-smartart.cxx8
-rw-r--r--sd/qa/unit/import-tests2.cxx14
-rw-r--r--sd/source/ui/view/drtxtob.cxx10
-rw-r--r--svx/source/svdraw/svdotext.cxx137
-rw-r--r--svx/source/svdraw/svdotextdecomposition.cxx2
-rw-r--r--svx/source/svdraw/svdoutl.cxx2
-rw-r--r--svx/source/unodraw/unoshape.cxx9
31 files changed, 452 insertions, 258 deletions
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;
}