diff --git a/oox/inc/drawingml/textbodyproperties.hxx b/oox/inc/drawingml/textbodyproperties.hxx index 46cf99614c56..2a977c879d7e 100644 --- a/oox/inc/drawingml/textbodyproperties.hxx +++ b/oox/inc/drawingml/textbodyproperties.hxx @@ -50,7 +50,7 @@ struct TextBodyProperties OUString msPrst; /// Normal autofit: font scale (default: 100%). sal_Int32 mnFontScale = 100000; - sal_Int32 mnSpacingScale = 100000; + sal_Int32 mnSpacingReduction = 0; OUString msHorzOverflow; std::optional< sal_Int32 > moVertOverflow{}; diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx index 2508513f89d1..a20d97debb89 100644 --- a/oox/source/drawingml/textbodypropertiescontext.cxx +++ b/oox/source/drawingml/textbodypropertiescontext.cxx @@ -238,9 +238,10 @@ ContextHandlerRef TextBodyPropertiesContext::onCreateContext( sal_Int32 aElement mrTextBodyProp.maPropertyMap.setProperty( PROP_TextFitToSize, TextFitToSizeType_AUTOFIT); mrTextBodyProp.maPropertyMap.setProperty(PROP_TextAutoGrowHeight, false); mrTextBodyProp.mnFontScale = rAttribs.getInteger(XML_fontScale, 100000); - mrTextBodyProp.mnSpacingScale = rAttribs.getInteger(XML_lnSpcReduction, 100000); - mrTextBodyProp.maPropertyMap.setProperty(PROP_TextFitToSizeFontScale, mrTextBodyProp.mnFontScale / 100000.0); - mrTextBodyProp.maPropertyMap.setProperty(PROP_TextFitToSizeSpacingScale, 1.0 - mrTextBodyProp.mnSpacingScale / 100000.0); + mrTextBodyProp.mnSpacingReduction = rAttribs.getInteger(XML_lnSpcReduction, 0); + // The two properties are percentages. + mrTextBodyProp.maPropertyMap.setProperty(PROP_TextFitToSizeFontScale, mrTextBodyProp.mnFontScale / 1000.0); + mrTextBodyProp.maPropertyMap.setProperty(PROP_TextFitToSizeSpacingScale, 100.0 - mrTextBodyProp.mnSpacingReduction / 1000.0); break; } case A_TOKEN( spAutoFit ): diff --git a/sd/qa/unit/TextFittingTest.cxx b/sd/qa/unit/TextFittingTest.cxx index 74bfce98e669..d45d379c579a 100644 --- a/sd/qa/unit/TextFittingTest.cxx +++ b/sd/qa/unit/TextFittingTest.cxx @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -203,6 +205,37 @@ CPPUNIT_TEST_FIXTURE(TextFittingTest, testTestBulletDifferenceViewAndEdit) CPPUNIT_ASSERT_EQUAL(false, pView->IsTextEdit()); } +CPPUNIT_TEST_FIXTURE(TextFittingTest, testStoredFitKeptUntilEdited) +{ + // The first slide stores a fit of 55 percent font with 20 percent less line spacing, though + // its text fits at full size. The stored fit is shown until the text is edited, and then the + // text is fitted afresh. + createSdImpressDoc("pptx/TextFittingStored.pptx"); + auto pXImpressDocument = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pXImpressDocument); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + auto pBody = DynCastSdrTextObj(pViewShell->GetActualPage()->GetObj(1)); + CPPUNIT_ASSERT(pBody); + + const SdrTextFitToSizeTypeItem& rStored = pBody->GetMergedItem(SDRATTR_TEXT_FITTOSIZE); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.55, rStored.getFontScale(), 1E-4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8, rStored.getSpacingScale(), 1E-4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.55, pBody->GetFontScale(), 1E-4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8, pBody->GetSpacingScale(), 1E-4); + + SdrView* pView = pViewShell->GetView(); + Scheduler::ProcessEventsToIdle(); + pView->SdrBeginTextEdit(pBody); + CPPUNIT_ASSERT(pView->IsTextEdit()); + EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); + rEditView.SetSelection(ESelection(0, 0)); + rEditView.InsertText(u"x"_ustr); + pView->SdrEndTextEdit(); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, pBody->GetFontScale(), 1E-4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, pBody->GetSpacingScale(), 1E-4); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/qa/unit/data/pptx/TextFittingStored.pptx b/sd/qa/unit/data/pptx/TextFittingStored.pptx new file mode 100644 index 000000000000..358f6a3c245e Binary files /dev/null and b/sd/qa/unit/data/pptx/TextFittingStored.pptx differ diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx index b3fac1d95bb1..779effae035c 100644 --- a/svx/source/svdraw/svdotxed.cxx +++ b/svx/source/svdraw/svdotxed.cxx @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -287,6 +289,18 @@ void SdrTextObj::EndTextEdit(SdrOutliner& rOutl) SetOutlinerParaObject(std::move(pNewText)); } + // The fit stored with the shape belongs to the text before the edit, so fit afresh. + if (IsAutoFit()) + { + SdrTextFitToSizeTypeItem aItem(GetObjectItem(SDRATTR_TEXT_FITTOSIZE)); + if (aItem.getFontScale() != 0.0 || aItem.getSpacingScale() != 0.0) + { + aItem.setFontScale(0.0); + aItem.setSpacingScale(0.0); + SetObjectItem(aItem); + } + } + if (isAnnotationObject()) { auto xTextAPI(getAnnotationData()->mxAnnotation->getTextApiObject()); diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index 2a412c6f6f59..61f59f2b8863 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -2341,26 +2341,27 @@ bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn } case OWN_ATTR_TEXTFITTOSIZE_FONT_SCALE: - { - double fScale = 0.0; - if (rValue >>= fScale) - { - SdrTextFitToSizeTypeItem aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE)); - aItem.setFontScale(fScale / 100.0); - pSdrObject->SetMergedItem(aItem); - return true; - } - break; - } - case OWN_ATTR_TEXTFITTOSIZE_SPACING_SCALE: { double fScale = 0.0; if (rValue >>= fScale) { - SdrTextFitToSizeTypeItem aItem(pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE)); - aItem.setSpacingScale(fScale / 100.0); - pSdrObject->SetMergedItem(aItem); + // A multi-property call may already hold the fit item to apply at the end. + std::optional& rCollected = mpImpl->moItemSet; + const bool bCollected = mbIsMultiPropertyCall && rCollected + && rCollected->GetItemState(SDRATTR_TEXT_FITTOSIZE) + == SfxItemState::SET; + SdrTextFitToSizeTypeItem aItem( + bCollected ? rCollected->Get(SDRATTR_TEXT_FITTOSIZE) + : pSdrObject->GetMergedItem(SDRATTR_TEXT_FITTOSIZE)); + if (pProperty->nWID == OWN_ATTR_TEXTFITTOSIZE_FONT_SCALE) + aItem.setFontScale(fScale / 100.0); + else + aItem.setSpacingScale(fScale / 100.0); + if (bCollected) + rCollected->Put(aItem); + else + pSdrObject->SetMergedItem(aItem); return true; } break;