summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2018-02-13 17:47:23 +0100
committerAndras Timar <andras.timar@collabora.com>2018-03-25 20:08:39 +0200
commitece07693152747e33343ce16428390f91561f4a7 (patch)
treef97e07aa96cbe60cf65bcc14f69c62e71bf56f46
parentf734ff65dfa8fd02a03f26c7b9d0a21692a6d5fb (diff)
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. Change-Id: I73657fdd663b540b436747cfeeef3c76e8fe388c Reviewed-on: https://gerrit.libreoffice.org/49742 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> (cherry picked from commit 2c2919cb591d88b11bb2e25e45d6f75923821457)
-rw-r--r--include/svx/svdotext.hxx2
-rw-r--r--oox/source/export/drawingml.cxx19
-rw-r--r--sd/qa/unit/data/pptx/font-scale.pptxbin0 -> 40239 bytes
-rw-r--r--sd/qa/unit/export-tests-ooxml2.cxx14
-rw-r--r--svx/source/svdraw/svdotext.cxx63
5 files changed, 97 insertions, 1 deletions
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index a2860906481f..4bd5ec29c410 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -211,6 +211,7 @@ protected:
virtual SdrObject* getFullDragClone() const override;
+
public:
const Point& GetTextEditOffset() const { return maTextEditOffset; }
void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; }
@@ -383,6 +384,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 481d01fc5813..25d4e23fbb5c 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2378,8 +2378,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
--- /dev/null
+++ b/sd/qa/unit/data/pptx/font-scale.pptx
Binary files differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 411eb5f1a09c..fda810363356 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -126,6 +126,7 @@ public:
void testTdf114848();
void testTdf107608();
void testTdf111786();
+ void testFontScale();
void testTdf115394();
void testTdf115394Zero();
@@ -179,6 +180,7 @@ public:
CPPUNIT_TEST(testTdf114848);
CPPUNIT_TEST(testTdf107608);
CPPUNIT_TEST(testTdf111786);
+ CPPUNIT_TEST(testFontScale);
CPPUNIT_TEST(testTdf115394);
CPPUNIT_TEST(testTdf115394Zero);
@@ -1368,6 +1370,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 4662f70df497..e9560e87bb33 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();