[Libreoffice-commits] core.git: include/svx oox/source sd/qa svx/source

Szymon Kłos szymon.klos at collabora.com
Fri Feb 16 16:27:52 UTC 2018


 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   |   14 +++++++
 svx/source/svdraw/svdotext.cxx       |   63 +++++++++++++++++++++++++++++++++++
 5 files changed, 97 insertions(+), 1 deletion(-)

New commits:
commit 2c2919cb591d88b11bb2e25e45d6f75923821457
Author: Szymon Kłos <szymon.klos at 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.
    
    Change-Id: I73657fdd663b540b436747cfeeef3c76e8fe388c
    Reviewed-on: https://gerrit.libreoffice.org/49742
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

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
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 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();


More information about the Libreoffice-commits mailing list