include/svx/svdotext.hxx | 2 + oox/source/export/drawingml.cxx | 19 ++++++++++ sd/qa/unit/data/pptx/font-scale.pptx |binary sd/qa/unit/export-tests-ooxml2.cxx | 17 +++++++++ svx/source/svdraw/svdotext.cxx | 63 +++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-)
New commits: commit 79b32f930b66e202778d93ea577eacf1ac9c5bc3 Author: Szymon Kłos <szymon.k...@collabora.com> Date: Tue Feb 13 17:47:23 2018 +0100 PPTX export scale for TextFitToSize MSO requires to save fontScale attribute to have all the text shown properly (with FitToSize property) Values are approximated, after any modification in MSO scale is recalculated. Squashed: 7a510effa4566d405d2033b6635b42c08d34dec8 2c2919cb591d88b11bb2e25e45d6f75923821457 Change-Id: I73657fdd663b540b436747cfeeef3c76e8fe388c Reviewed-on: https://gerrit.libreoffice.org/49742 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/49969 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx index 132a77800c14..45819d59ced1 100644 --- a/include/svx/svdotext.hxx +++ b/include/svx/svdotext.hxx @@ -215,6 +215,7 @@ protected: virtual SdrObject* getFullDragClone() const override; + public: const Point& GetTextEditOffset() const { return maTextEditOffset; } void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; } @@ -390,6 +391,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 aa9ba6a4dfac..cc5cf27bc47b 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2325,8 +2325,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 new file mode 100644 index 000000000000..df33b20cebca Binary files /dev/null and b/sd/qa/unit/data/pptx/font-scale.pptx differ diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 80518487b96a..7cfb05b3228a 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -125,6 +125,7 @@ public: void testGroupsRotatedPosition(); void testAccentColor(); void testTdf114848(); + void testFontScale(); void testTdf115394(); void testTdf115394Zero(); @@ -173,6 +174,7 @@ public: CPPUNIT_TEST(testGroupsRotatedPosition); CPPUNIT_TEST(testAccentColor); CPPUNIT_TEST(testTdf114848); + CPPUNIT_TEST(testFontScale); CPPUNIT_TEST(testTdf115394); CPPUNIT_TEST(testTdf115394Zero); @@ -1134,6 +1136,21 @@ void SdOOXMLExportTest2::testGroupRotation() assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:grpSp/p:sp[2]/p:spPr/a:xfrm", "rot", "20400000"); } +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"); + + // Rounding errors possible, approximate value + OUString sScale = getXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale"); + if (sScale != "73000" && sScale != "72000" && sScale != "74000") + CPPUNIT_ASSERT_EQUAL(OUString("73000"), sScale); + + 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 6824c46bad95..e7ba56e1aac6 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1267,6 +1267,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(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits