diff options
-rw-r--r-- | editeng/inc/editdoc.hxx | 14 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 9 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 22 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 139 | ||||
-rw-r--r-- | include/editeng/editdata.hxx | 4 | ||||
-rw-r--r-- | include/editeng/outliner.hxx | 2 | ||||
-rw-r--r-- | include/svx/svdotext.hxx | 6 | ||||
-rw-r--r-- | sd/qa/unit/TextFittingTest.cxx | 12 | ||||
-rw-r--r-- | sd/qa/unit/data/xml/n593612_0.xml | 4 | ||||
-rw-r--r-- | sd/qa/unit/export-tests-ooxml3.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdotext.cxx | 133 | ||||
-rw-r--r-- | svx/source/svdraw/svdotextdecomposition.cxx | 4 | ||||
-rw-r--r-- | svx/source/svdraw/svdotxed.cxx | 2 |
13 files changed, 183 insertions, 170 deletions
diff --git a/editeng/inc/editdoc.hxx b/editeng/inc/editdoc.hxx index 80e3cc34243c..8e17c6c38fa6 100644 --- a/editeng/inc/editdoc.hxx +++ b/editeng/inc/editdoc.hxx @@ -662,7 +662,9 @@ public: class ParaPortionList { mutable sal_Int32 nLastCache; - std::vector<std::unique_ptr<ParaPortion>> maPortions; + typedef std::vector<std::unique_ptr<ParaPortion>> ParaPortionContainerType; + ParaPortionContainerType maPortions; + public: ParaPortionList(); ~ParaPortionList(); @@ -684,6 +686,16 @@ public: void Append(std::unique_ptr<ParaPortion> p); sal_Int32 Count() const; + ParaPortion& getRef(sal_Int32 nPosition) { return *maPortions[nPosition]; } + ParaPortion const& getRef(sal_Int32 nPosition) const { return *maPortions[nPosition]; } + + sal_Int32 lastIndex() const { return Count() - 1; } + + ParaPortionContainerType::iterator begin() { return maPortions.begin(); } + ParaPortionContainerType::iterator end() { return maPortions.end(); } + ParaPortionContainerType::const_iterator cbegin() const { return maPortions.cbegin(); } + ParaPortionContainerType::const_iterator cend() const { return maPortions.cend(); } + #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG // temporary: static void DbgCheck(ParaPortionList const&, EditDoc const& rDoc); diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index 34d57e8e9747..988c446aca57 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -530,6 +530,7 @@ private: Color maBackgroundColor; + ScalingParameters maCustomScalingParameters; ScalingParameters maScalingParameters; bool mbRoundToNearestPt; @@ -617,6 +618,7 @@ private: void ParaAttribsChanged( ContentNode const * pNode, bool bIgnoreUndoCheck = false ); void TextModified(); void CalcHeight( ParaPortion* pPortion ); + bool isInEmptyClusterAtTheEnd(ParaPortion& rParaPortion); void InsertUndo( std::unique_ptr<EditUndo> pUndo, bool bTryMerge = false ); void ResetUndoManager(); @@ -880,8 +882,11 @@ public: void SetMinColumnWrapHeight(tools::Long nVal) { mnMinColumnWrapHeight = nVal; } - void FormatDoc(); - void FormatFullDoc(); + tools::Long FormatParagraphs(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs); + void ScaleContentToFitWindow(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs); + void FormatDoc(); + void FormatFullDoc(); + void UpdateViews( EditView* pCurView = nullptr ); void Paint( ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* pTargetDevice ); void Paint(OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, bool bStripOnly = false, Degree10 nOrientation = 0_deg10); diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 8c5265e1304e..048226658d4e 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -4376,12 +4376,31 @@ tools::Long ImpEditEngine::GetXPos( return nX; } +/** Is true if paragraph is in the empty cluster of paragraphs at the end */ +bool ImpEditEngine::isInEmptyClusterAtTheEnd(ParaPortion& rPortion) +{ + sal_Int32 nPortion = GetParaPortions().GetPos(&rPortion); + + auto& rParagraphs = GetParaPortions(); + if (rParagraphs.Count() <= 0) + return false; + + sal_Int32 nCurrent = rParagraphs.lastIndex(); + while (nCurrent > 0 && rParagraphs.getRef(nCurrent).IsEmpty()) + { + if (nCurrent == nPortion) + return true; + nCurrent--; + } + return false; +} + void ImpEditEngine::CalcHeight( ParaPortion* pPortion ) { pPortion->nHeight = 0; pPortion->nFirstLineOffset = 0; - if ( !pPortion->IsVisible() ) + if (!pPortion->IsVisible() || isInEmptyClusterAtTheEnd(*pPortion)) return; OSL_ENSURE( pPortion->GetLines().Count(), "Paragraph with no lines in ParaPortion::CalcHeight" ); @@ -4416,7 +4435,6 @@ void ImpEditEngine::CalcHeight( ParaPortion* pPortion ) pPortion->nHeight += scaleYSpacingValue(rULItem.GetLower()); // not in the last } - if ( !nPortion || maStatus.ULSpaceSummation() ) return; diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 79c943516bc7..464e9ed07550 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -392,53 +392,39 @@ bool ImpEditEngine::IsPageOverflow( ) const void ImpEditEngine::FormatFullDoc() { - for ( sal_Int32 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ ) - GetParaPortions()[nPortion]->MarkSelectionInvalid( 0 ); + for ( sal_Int32 nPortion = 0; nPortion < maParaPortionList.Count(); nPortion++ ) + maParaPortionList[nPortion]->MarkSelectionInvalid( 0 ); FormatDoc(); } -void ImpEditEngine::FormatDoc() +tools::Long ImpEditEngine::FormatParagraphs(o3tl::sorted_vector<sal_Int32>& aRepaintParagraphList) { - if (!IsUpdateLayout() || IsFormatting()) - return; - - mbIsFormatting = true; - - // Then I can also start the spell-timer... - if ( GetStatus().DoOnlineSpelling() ) - StartOnlineSpellTimer(); - + sal_Int32 nParaCount = maParaPortionList.Count(); tools::Long nY = 0; bool bGrow = false; - // Here already, so that not always in CreateLines... - bool bMapChanged = ImpCheckRefMapMode(); - sal_Int32 nParaCount = GetParaPortions().Count(); - o3tl::sorted_vector<sal_Int32> aRepaintParas; - aRepaintParas.reserve(nParaCount); - - for ( sal_Int32 nPara = 0; nPara < nParaCount; nPara++ ) + for (sal_Int32 nParagraph = 0; nParagraph < nParaCount; nParagraph++) { - ParaPortion* pParaPortion = GetParaPortions()[nPara]; - if ( pParaPortion->MustRepaint() || ( pParaPortion->IsInvalid() && pParaPortion->IsVisible() ) ) + ParaPortion& rParaPortion = maParaPortionList.getRef(nParagraph); + if (rParaPortion.MustRepaint() || (rParaPortion.IsInvalid() && rParaPortion.IsVisible())) { // No formatting should be necessary for MustRepaint()! - if ( !pParaPortion->IsInvalid() || CreateLines( nPara, nY ) ) + if (CreateLines(nParagraph, nY)) { - if ( !bGrow && GetTextRanger() ) + if (!bGrow && GetTextRanger()) { // For a change in height all below must be reformatted... - for ( sal_Int32 n = nPara+1; n < GetParaPortions().Count(); n++ ) + for (sal_Int32 n = nParagraph + 1; n < nParaCount; n++) { - ParaPortion* pPP = GetParaPortions()[n]; - pPP->MarkSelectionInvalid( 0 ); - pPP->GetLines().Reset(); + ParaPortion& rParaPortionToInvalidate = maParaPortionList.getRef(n); + rParaPortionToInvalidate.MarkSelectionInvalid(0); + rParaPortionToInvalidate.GetLines().Reset(); } } bGrow = true; - if ( IsCallParaInsertedOrDeleted() ) + if (IsCallParaInsertedOrDeleted()) { - GetEditEnginePtr()->ParagraphHeightChanged( nPara ); + GetEditEnginePtr()->ParagraphHeightChanged(nParagraph); for (EditView* pView : aEditViews) { @@ -447,13 +433,90 @@ void ImpEditEngine::FormatDoc() } } - pParaPortion->SetMustRepaint( false ); + rParaPortion.SetMustRepaint(false); } - aRepaintParas.insert(nPara); + aRepaintParagraphList.insert(nParagraph); } - nY += pParaPortion->GetHeight(); + nY += rParaPortion.GetHeight(); } + return nY; +} + +namespace +{ +constexpr std::array<ScalingParameters, 13> constScaleLevels = +{ + ScalingParameters{100.0, 100.0, 100.0, 90.0 }, + ScalingParameters{ 92.5, 92.5, 100.0, 90.0 }, + ScalingParameters{ 92.5, 92.5, 100.0, 80.0 }, + ScalingParameters{ 85.0, 85.0, 100.0, 90.0 }, + ScalingParameters{ 85.0, 85.0, 100.0, 80.0 }, + ScalingParameters{ 77.5, 77.5, 100.0, 80.0 }, + ScalingParameters{ 70.0, 70.0, 100.0, 80.0 }, + ScalingParameters{ 62.5, 62.5, 100.0, 80.0 }, + ScalingParameters{ 55.0, 55.0, 100.0, 80.0 }, + ScalingParameters{ 47.5, 47.5, 100.0, 80.0 }, + ScalingParameters{ 40.0, 40.0, 100.0, 80.0 }, + ScalingParameters{ 32.5, 32.5, 100.0, 80.0 }, + ScalingParameters{ 25.0, 25.0, 100.0, 80.0 }, +}; + +} // end anonymous ns + +void ImpEditEngine::ScaleContentToFitWindow(o3tl::sorted_vector<sal_Int32>& aRepaintParagraphList) +{ + if (!maCustomScalingParameters.areValuesDefault()) + maScalingParameters = maCustomScalingParameters; + + tools::Long nHeight = FormatParagraphs(aRepaintParagraphList); + bool bOverflow = nHeight > (maMaxAutoPaperSize.Height() * mnColumns); + + size_t nCurrentScaleLevel = 0; + while (bOverflow && nCurrentScaleLevel < constScaleLevels.size()) + { + // Clean-up and reset paragraphs + aRepaintParagraphList.clear(); + for (auto& pParaPortionToInvalidate : maParaPortionList) + { + pParaPortionToInvalidate->GetLines().Reset(); + pParaPortionToInvalidate->MarkSelectionInvalid(0); + pParaPortionToInvalidate->SetMustRepaint(true); + } + + // Get new scaling parameters + maScalingParameters = constScaleLevels[nCurrentScaleLevel]; + + // Try again with different scaling factor + nHeight = FormatParagraphs(aRepaintParagraphList); + bOverflow = nHeight > (maMaxAutoPaperSize.Height() * mnColumns); + + // Increase scale level + nCurrentScaleLevel++; + } +} + +void ImpEditEngine::FormatDoc() +{ + if (!IsUpdateLayout() || IsFormatting()) + return; + + mbIsFormatting = true; + + // Then I can also start the spell-timer... + if (GetStatus().DoOnlineSpelling()) + StartOnlineSpellTimer(); + + // Reserve, as it should match the current number of paragraphs + bool bMapChanged = ImpCheckRefMapMode(); + + o3tl::sorted_vector<sal_Int32> aRepaintParagraphList; + aRepaintParagraphList.reserve(maParaPortionList.Count()); + + if (maStatus.DoStretch()) + ScaleContentToFitWindow(aRepaintParagraphList); + else + FormatParagraphs(aRepaintParagraphList); aInvalidRect = tools::Rectangle(); // make empty @@ -493,10 +556,10 @@ void ImpEditEngine::FormatDoc() } } - if (!aRepaintParas.empty()) + if (!aRepaintParagraphList.empty()) { auto CombineRepaintParasAreas = [&](const LineAreaInfo& rInfo) { - if (aRepaintParas.count(rInfo.nPortion)) + if (aRepaintParagraphList.count(rInfo.nPortion)) aInvalidRect.Union(rInfo.aArea); return CallbackResult::Continue; }; @@ -1015,9 +1078,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) if (maStatus.DoStretch() && (fFontScalingX != 100.0)) nCurPos = basegfx::fround(double(nCurPos) * 100.0 / std::max(fFontScalingX, 1.0)); - short nAllSpaceBeforeText = static_cast< short >(rLRItem.GetTextLeft()/* + rLRItem.GetTextLeft()*/ + nSpaceBeforeAndMinLabelWidth); - aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText /*rLRItem.GetTextLeft()*/, maEditDoc.GetDefTab() ); - aCurrentTab.nTabPos = scaleXFontValue(tools::Long(aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText/*rLRItem.GetTextLeft()*/)); + short nAllSpaceBeforeText = short(rLRItem.GetTextLeft()); + aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText , maEditDoc.GetDefTab() ); + aCurrentTab.nTabPos = tools::Long(aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText); aCurrentTab.bValid = false; // Switch direction in R2L para... @@ -4470,7 +4533,7 @@ void ImpEditEngine::setScalingParameters(ScalingParameters const& rScalingParame } bool bScalingChanged = maScalingParameters != aNewScalingParameters; - maScalingParameters = aNewScalingParameters; + maCustomScalingParameters = maScalingParameters = aNewScalingParameters; if (bScalingChanged && maStatus.DoStretch()) { diff --git a/include/editeng/editdata.hxx b/include/editeng/editdata.hxx index 6225ef897b2f..a4a160cc171f 100644 --- a/include/editeng/editdata.hxx +++ b/include/editeng/editdata.hxx @@ -282,6 +282,10 @@ struct ScalingParameters && fSpacingX == rOther.fSpacingX && fSpacingY == rOther.fSpacingY; } + bool areValuesDefault() + { + return fFontX == 100.0 && fFontY == 100.0 && fSpacingX == 100.0 && fSpacingY == 100.0; + } }; struct EECharAttrib diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx index ccc7dafe822a..8733e4c4d429 100644 --- a/include/editeng/outliner.hxx +++ b/include/editeng/outliner.hxx @@ -897,7 +897,7 @@ public: /// Set attributes from rSet an all characters of nPara. void SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet); void RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich = 0 ); - void QuickFormatDoc(); + void QuickFormatDoc(); bool UpdateFields(); void RemoveFields( const std::function<bool ( const SvxFieldData* )>& isFieldData = [] (const SvxFieldData* ){return true;} ); diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx index d9c0908e505b..f3c3a300eed7 100644 --- a/include/svx/svdotext.hxx +++ b/include/svx/svdotext.hxx @@ -273,9 +273,9 @@ private: tools::Rectangle& rAnchorRect, tools::Rectangle& rPaintRect, 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, bool bIsVerticalWriting) const; + + void setupAutoFitText( SdrOutliner& rOutliner ) const; + void setupAutoFitText(SdrOutliner& rOutliner, const Size& rShapeSize) const; SVX_DLLPRIVATE rtl::Reference<SdrObject> ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const; SVX_DLLPRIVATE void ImpRegisterLink(); diff --git a/sd/qa/unit/TextFittingTest.cxx b/sd/qa/unit/TextFittingTest.cxx index e88a2680f005..e4d37c0149bf 100644 --- a/sd/qa/unit/TextFittingTest.cxx +++ b/sd/qa/unit/TextFittingTest.cxx @@ -74,16 +74,16 @@ CPPUNIT_TEST_FIXTURE(TextFittingTest, testTest) Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pEditEngine->GetParagraphCount()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(87.49, pEditEngine->getScalingParameters().fFontY, 1E-2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(90.0, pEditEngine->getScalingParameters().fSpacingY, 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(92.5, pEditEngine->getScalingParameters().fFontY, 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80.0, pEditEngine->getScalingParameters().fSpacingY, 1E-2); // Add paragraph 5 rEditView.SetSelection(ESelection(4, 0, 4, 0)); rEditView.InsertText(u"\nD5"_ustr); CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pEditEngine->GetParagraphCount()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(54.68, pEditEngine->getScalingParameters().fFontY, 1E-2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pEditEngine->getScalingParameters().fSpacingY, 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(70.0, pEditEngine->getScalingParameters().fFontY, 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80.0, pEditEngine->getScalingParameters().fSpacingY, 1E-2); // Add paragraph 6 rEditView.SetSelection(ESelection(5, 0, 5, 0)); @@ -105,8 +105,8 @@ CPPUNIT_TEST_FIXTURE(TextFittingTest, testTest) rEditView.DeleteSelected(); CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pEditEngine->GetParagraphCount()); - // not ideal - scaling should be 100%, but close enough - CPPUNIT_ASSERT_DOUBLES_EQUAL(99.05, pEditEngine->getScalingParameters().fFontY, 1E-2); + // We are back to 100% + CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pEditEngine->getScalingParameters().fFontY, 1E-2); CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pEditEngine->getScalingParameters().fSpacingY, 1E-2); // are we still in text edit mode? diff --git a/sd/qa/unit/data/xml/n593612_0.xml b/sd/qa/unit/data/xml/n593612_0.xml index 3f5f88e445f1..0639294c5007 100644 --- a/sd/qa/unit/data/xml/n593612_0.xml +++ b/sd/qa/unit/data/xml/n593612_0.xml @@ -1,6 +1,6 @@ <?xml version="1.0"?> <XShapes> - <XShape positionX="11429" positionY="1324" sizeX="2259" sizeY="15209" type="com.sun.star.drawing.CustomShape" name="Rectangle 52" text=" " fontHeight="24.000000" fontColor="ffffffff" textAutoGrowHeight="true" textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" textHorizontalAdjust="CENTER" textVerticalAdjust="TOP" textLeftDistance="254" textRightDistance="254" textUpperDistance="127" textLowerDistance="127" textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" textAnimationStartInside="false" textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="SOLID" fillColor="3c8c93" fillTransparence="0" fillTransparenceGradientName=""> + <XShape positionX="11429" positionY="1324" sizeX="2259" sizeY="15124" type="com.sun.star.drawing.CustomShape" name="Rectangle 52" text=" " fontHeight="24.000000" fontColor="ffffffff" textAutoGrowHeight="true" textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" textHorizontalAdjust="CENTER" textVerticalAdjust="TOP" textLeftDistance="254" textRightDistance="254" textUpperDistance="127" textLowerDistance="127" textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" textAnimationStartInside="false" textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="SOLID" fillColor="3c8c93" fillTransparence="0" fillTransparenceGradientName=""> <FillTransparenceGradient style="LINEAR" startColor="000000" endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/> <FillGradient style="LINEAR" startColor="3465a4" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/> <FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/> @@ -10,7 +10,7 @@ <LineEnd/> <Transformation> <Line1 column1="2260.000000" column2="0.000000" column3="11429.000000"/> - <Line2 column1="0.000000" column2="15210.000000" column3="1324.000000"/> + <Line2 column1="0.000000" column2="15125.000000" column3="1324.000000"/> <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/> </Transformation> <CustomShapeGeometry> diff --git a/sd/qa/unit/export-tests-ooxml3.cxx b/sd/qa/unit/export-tests-ooxml3.cxx index 106073c47816..447f014dbf5e 100644 --- a/sd/qa/unit/export-tests-ooxml3.cxx +++ b/sd/qa/unit/export-tests-ooxml3.cxx @@ -226,7 +226,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testFontScale) OUString sScale = getXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit"_ostr, "fontScale"_ostr); - CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(81111), sScale.toInt32(), 1000); + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(85000), sScale.toInt32(), 1000); } CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testShapeAutofitPPTX) diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index 0f25ce9095a1..986e2c7a4126 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1234,14 +1234,14 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame, } else if (IsAutoFit()) { - ImpAutoFitText(rOutliner); + setupAutoFitText(rOutliner); } } double SdrTextObj::GetFontScale() const { SdrOutliner& rOutliner = ImpGetDrawOutliner(); - // This eventually calls ImpAutoFitText + // This eventually calls setupAutoFitText UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle())); return rOutliner.getScalingParameters().fFontY; @@ -1250,133 +1250,41 @@ double SdrTextObj::GetFontScale() const double SdrTextObj::GetSpacingScale() const { SdrOutliner& rOutliner = ImpGetDrawOutliner(); - // This eventually calls ImpAutoFitText + // This eventually calls setupAutoFitText UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle())); return rOutliner.getScalingParameters().fSpacingY; } -void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const +void SdrTextObj::setupAutoFitText(SdrOutliner& rOutliner) const { - const Size aShapeSize=GetSnapRect().GetSize(); - ImpAutoFitText( rOutliner, - Size(aShapeSize.Width()-GetTextLeftDistance()-GetTextRightDistance(), - aShapeSize.Height()-GetTextUpperDistance()-GetTextLowerDistance()), - IsVerticalWriting() ); -} + const Size aShapeSize = GetSnapRect().GetSize(); + Size aSize(aShapeSize.Width() - GetTextLeftDistance() - GetTextRightDistance(), + aShapeSize.Height() - GetTextUpperDistance() - GetTextLowerDistance()); -void SdrTextObj::ImpAutoFitText(SdrOutliner& rOutliner, const Size& rTextSize, - bool bIsVerticalWriting) const -{ - autoFitTextForCompatibility(rOutliner, rTextSize, bIsVerticalWriting); + setupAutoFitText(rOutliner, aSize); } - -void SdrTextObj::autoFitTextForCompatibility(SdrOutliner& rOutliner, const Size& rTextBoxSize, bool bIsVerticalWriting) const +void SdrTextObj::setupAutoFitText(SdrOutliner& rOutliner, const Size& rTextBoxSize) const { - rOutliner.setRoundFontSizeToPt(true); + rOutliner.setRoundFontSizeToPt(true); // We need to round the font size nearest integer pt size + rOutliner.SetMaxAutoPaperSize(rTextBoxSize); + rOutliner.SetPaperSize(rTextBoxSize); const SdrTextFitToSizeTypeItem& rItem = GetObjectItem(SDRATTR_TEXT_FITTOSIZE); - double fMaxScale = rItem.getFontScale(); - if (fMaxScale > 0.0) - { - rOutliner.setScalingParameters({ fMaxScale, fMaxScale, 100.0, 100.0 }); - } - else - { - fMaxScale = 100.0; - } - - Size aCurrentTextBoxSize = rOutliner.CalcTextSizeNTP(); - if (aCurrentTextBoxSize.Height() == 0) - return; - tools::Long nExtendTextBoxBy = -50; - aCurrentTextBoxSize.extendBy(0, nExtendTextBoxBy); - double fCurrentFitFactor = 1.0; + double fFontScale = rItem.getFontScale(); + double fSpacingScale = rItem.getSpacingScale(); - if (bIsVerticalWriting) - fCurrentFitFactor = double(rTextBoxSize.Width()) / aCurrentTextBoxSize.Width(); - else - fCurrentFitFactor = double(rTextBoxSize.Height()) / aCurrentTextBoxSize.Height(); - - auto aParameters = rOutliner.getScalingParameters(); - double fInitialFontScaleY = aParameters.fFontY; - double fInitialSpacing = aParameters.fSpacingY; - - if (fCurrentFitFactor >= 1.0 && fInitialFontScaleY >= 100.0 && fInitialSpacing >= 100.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 = 100.0; - double fBestFitFactor = fCurrentFitFactor; - - if (fCurrentFitFactor >= 1.0) + if (fFontScale > 0.0 && fSpacingScale > 0.0 && !mbInEditMode) { - fMinY = fInitialFontScaleY; - fBestFontScale = fInitialFontScaleY; - fBestSpacing = fInitialSpacing; - fBestFitFactor = fCurrentFitFactor; + rOutliner.setScalingParameters({ fFontScale, fFontScale, 100.0, fSpacingScale }); } else { - fMaxY = std::min(fInitialFontScaleY, fMaxScale); + rOutliner.resetScalingParameters(); } - 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.setScalingParameters({ fCurrentFontScale, fCurrentFontScale, 100.0, fCurrentSpacing }); - - aCurrentTextBoxSize = rOutliner.CalcTextSizeNTP(); - aCurrentTextBoxSize.extendBy(0, nExtendTextBoxBy); - if (bIsVerticalWriting) - fCurrentFitFactor = double(rTextBoxSize.Width()) / aCurrentTextBoxSize.Width(); - else - 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.setScalingParameters({ fBestFontScale, fBestFontScale, 100.0, fBestSpacing }); + rOutliner.QuickFormatDoc(); } void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, tools::Rectangle& rPaintRect ) const @@ -1967,10 +1875,13 @@ void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus ) assert(mpEditingOutliner); mbInDownScale = true; + // Need to reset scaling so it searches for the fitting size again + mpEditingOutliner->resetScalingParameters(); + // sucks that we cannot disable paints via // mpEditingOutliner->SetUpdateMode(FALSE) - but EditEngine skips // formatting as well, then. - ImpAutoFitText(*mpEditingOutliner); + setupAutoFitText(*mpEditingOutliner); mbInDownScale = false; } } diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx index 84f440b81121..5a9abfe654b3 100644 --- a/svx/source/svdraw/svdotextdecomposition.cxx +++ b/svx/source/svdraw/svdotextdecomposition.cxx @@ -937,11 +937,11 @@ void SdrTextObj::impDecomposeAutoFitTextPrimitive( rOutliner.SetMinColumnWrapHeight(nAnchorTextWidth); } - rOutliner.SetPaperSize(aNullSize); + rOutliner.SetPaperSize(aAnchorTextSize); rOutliner.SetUpdateLayout(true); rOutliner.SetText(*pOutlinerParaObject); - ImpAutoFitText(rOutliner,aAnchorTextSize,bVerticalWriting); + setupAutoFitText(rOutliner, aAnchorTextSize); // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage())); diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx index 120bf26b1751..8666f262be92 100644 --- a/svx/source/svdraw/svdotxed.cxx +++ b/svx/source/svdraw/svdotxed.cxx @@ -110,7 +110,7 @@ bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl) } else if (IsAutoFit()) { - ImpAutoFitText(rOutl); + setupAutoFitText(rOutl); } if(pOutlinerParaObject) |