diff options
-rw-r--r-- | include/svx/svdotext.hxx | 2 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 19 | ||||
-rw-r--r-- | sd/qa/unit/data/pptx/font-scale.pptx | bin | 0 -> 40239 bytes | |||
-rw-r--r-- | sd/qa/unit/export-tests-ooxml2.cxx | 14 | ||||
-rw-r--r-- | svx/source/svdraw/svdotext.cxx | 63 |
5 files changed, 97 insertions, 1 deletions
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx index 4f862638ce8b..dd9972b3ce56 100644 --- a/include/svx/svdotext.hxx +++ b/include/svx/svdotext.hxx @@ -213,6 +213,7 @@ protected: virtual SdrObject* getFullDragClone() const override; + public: const Point& GetTextEditOffset() const { return maTextEditOffset; } void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; } @@ -385,6 +386,7 @@ public: // FitToSize and Fontwork are not taken into account in GetTextSize()! virtual const Size& GetTextSize() const; void FitFrameToTextSize(); + double GetFontScaleY() const; // Simultaneously sets the text into the Outliner (possibly // the one of the EditOutliner) and sets the PaperSize. diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 0503a088faf7..52807f28be3d 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2553,8 +2553,25 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin TextFitToSizeType eFit = TextFitToSizeType_NONE; if (GETA(TextFitToSize)) mAny >>= eFit; + if (eFit == TextFitToSizeType_AUTOFIT) - mpFS->singleElementNS(XML_a, XML_normAutofit, FSEND); + { + const sal_Int32 MAX_SCALE_VAL = 100000; + sal_Int32 nFontScale = MAX_SCALE_VAL; + SvxShapeText* pTextShape = dynamic_cast<SvxShapeText*>(rXIface.get()); + if (pTextShape) + { + SdrTextObj* pTextObject = dynamic_cast<SdrTextObj*>(pTextShape->GetSdrObject()); + if (pTextObject) + { + double fScaleY = pTextObject->GetFontScaleY(); + nFontScale = static_cast<sal_uInt32>(fScaleY * 100) * 1000; + } + } + + mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale, + ( nFontScale < MAX_SCALE_VAL && nFontScale > 0 ) ? I32S(nFontScale) : nullptr, FSEND); + } } mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr); } diff --git a/sd/qa/unit/data/pptx/font-scale.pptx b/sd/qa/unit/data/pptx/font-scale.pptx Binary files differnew file mode 100644 index 000000000000..df33b20cebca --- /dev/null +++ b/sd/qa/unit/data/pptx/font-scale.pptx diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 062dab0c4cd0..51e13eb80a5e 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -128,6 +128,7 @@ public: void testTdf90626(); void testTdf107608(); void testTdf111786(); + void testFontScale(); void testTdf115394(); void testTdf115394Zero(); @@ -183,6 +184,7 @@ public: CPPUNIT_TEST(testTdf90626); CPPUNIT_TEST(testTdf107608); CPPUNIT_TEST(testTdf111786); + CPPUNIT_TEST(testFontScale); CPPUNIT_TEST(testTdf115394); CPPUNIT_TEST(testTdf115394Zero); @@ -1406,6 +1408,18 @@ void SdOOXMLExportTest2::testTdf111786() xDocShRef->DoClose(); } +void SdOOXMLExportTest2::testFontScale() +{ + sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/font-scale.pptx"), PPTX); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile); + xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml"); + + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale", "73000"); + + xDocShRef->DoClose(); +} + void SdOOXMLExportTest2::testTdf115394() { sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115394.pptx"), PPTX); diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index a0cf962a7671..4a9f69d1afe3 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1259,6 +1259,69 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame, } } +double SdrTextObj::GetFontScaleY() const +{ + SdrText* pText = getActiveText(); + if (pText == nullptr || !pText->GetOutlinerParaObject() || pModel == nullptr) + return 1.0; + + SdrOutliner& rOutliner = ImpGetDrawOutliner(); + const Size aShapeSize = GetSnapRect().GetSize(); + const Size aSize = Size(aShapeSize.Width() - GetTextLeftDistance() - GetTextRightDistance(), + aShapeSize.Height() - GetTextUpperDistance() - GetTextLowerDistance()); + + rOutliner.SetPaperSize(aSize); + rOutliner.SetUpdateMode(true); + rOutliner.SetText(*pText->GetOutlinerParaObject()); + bool bIsVerticalWriting = IsVerticalWriting(); + + // Algorithm from SdrTextObj::ImpAutoFitText + + sal_uInt16 nMinStretchX = 0, nMinStretchY = 0; + sal_uInt16 nCurrStretchX = 100, nCurrStretchY = 100; + sal_uInt16 aOldStretchXVals[] = { 0,0,0 }; + const size_t aStretchArySize = SAL_N_ELEMENTS(aOldStretchXVals); + for (unsigned int i = 0; i<aStretchArySize; ++i) + { + const Size aCurrTextSize = rOutliner.CalcTextSizeNTP(); + double fFactor(1.0); + if (bIsVerticalWriting) + { + if (aCurrTextSize.Width() != 0) + { + fFactor = double(aSize.Width()) / aCurrTextSize.Width(); + } + } + else if (aCurrTextSize.Height() != 0) + { + fFactor = double(aSize.Height()) / aCurrTextSize.Height(); + } + fFactor = std::sqrt(fFactor); + + rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY); + + if (fFactor >= 1.0) + { + nMinStretchX = std::max(nMinStretchX, nCurrStretchX); + nMinStretchY = std::max(nMinStretchY, nCurrStretchY); + } + + aOldStretchXVals[i] = nCurrStretchX; + if (std::find(aOldStretchXVals, aOldStretchXVals + i, nCurrStretchX) != aOldStretchXVals + i) + break; // same value already attained once; algo is looping, exit + + if (fFactor < 1.0 || nCurrStretchX != 100) + { + nCurrStretchX = sal::static_int_cast<sal_uInt16>(nCurrStretchX*fFactor); + nCurrStretchY = sal::static_int_cast<sal_uInt16>(nCurrStretchY*fFactor); + rOutliner.SetGlobalCharStretching(std::min(sal_uInt16(100), nCurrStretchX), + std::min(sal_uInt16(100), nCurrStretchY)); + } + } + + return std::min(sal_uInt16(100), nCurrStretchY) / 100.0; +} + void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const { const Size aShapeSize=GetSnapRect().GetSize(); |