[Libreoffice-commits] core.git: sw/qa sw/source

Justin Luth justin_luth at sil.org
Mon Nov 7 04:10:07 UTC 2016


 sw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport3.cxx               |   13 ++++
 sw/qa/extras/ww8export/data/tdf41542_imagePadding.odt   |binary
 sw/qa/extras/ww8export/ww8export.cxx                    |   33 ++++++++---
 sw/source/filter/ww8/docxattributeoutput.cxx            |   35 ++++++++----
 sw/source/filter/ww8/docxattributeoutput.hxx            |    2 
 sw/source/filter/ww8/escher.hxx                         |    2 
 sw/source/filter/ww8/wrtw8esh.cxx                       |   45 +++++++++++-----
 8 files changed, 95 insertions(+), 35 deletions(-)

New commits:
commit 8eff1decd91cbfb10094c25d4cf1d2b434a4da72
Author: Justin Luth <justin_luth at sil.org>
Date:   Fri Nov 4 21:32:38 2016 +0300

    tdf#41542 MSWordExport: accommodate image's borderless padding
    
    Honor the padding value even if the border is not visible.
    Previously the padding information was just thrown out, and
    the image scaled to fill the entire image size.
    
    The unit test for tdf#77454 needed to be tweaked because surprisingly
    it has border padding of 1 - which this patch turns into a negative crop.
    
    Change-Id: I866d26e00f27221239d3291404f70fb57ac0896d
    Reviewed-on: https://gerrit.libreoffice.org/30578
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Justin Luth <justin_luth at sil.org>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odt b/sw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odt
new file mode 100755
index 0000000..019e19f
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index 4d73a7f..f93ace6 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
@@ -771,6 +771,19 @@ DECLARE_OOXMLEXPORT_TEST(testPNGImageCrop, "test_PNG_ImageCrop.docx")
 #endif
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf41542_imagePadding, "tdf41542_imagePadding.odt")
+{
+    // borderlessImage - image WITHOUT BORDERS : simulate padding with -crop
+    text::GraphicCrop crop = getProperty<text::GraphicCrop>(getShape(2), "GraphicCrop");
+    CPPUNIT_ASSERT( crop.Left != 0 && crop.Right != 0 );
+    CPPUNIT_ASSERT( crop.Left == crop.Top && crop.Right == crop.Bottom && crop.Left == crop.Right);
+
+    // borderedImage - image WITH BORDERS : simulate padding with -crop
+    crop = getProperty<text::GraphicCrop>(getShape(3), "GraphicCrop");
+    CPPUNIT_ASSERT( crop.Left != 0 && crop.Right != 0 );
+    CPPUNIT_ASSERT( crop.Left == crop.Top && crop.Right == crop.Bottom && crop.Left == crop.Right);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testFootnoteParagraphTag, "testFootnote.docx")
 {
     /* In footnotes.xml, the paragraph tag inside <w:footnote w:id="2"> was getting written into document.xml.
diff --git a/sw/qa/extras/ww8export/data/tdf41542_imagePadding.odt b/sw/qa/extras/ww8export/data/tdf41542_imagePadding.odt
new file mode 100755
index 0000000..019e19f
Binary files /dev/null and b/sw/qa/extras/ww8export/data/tdf41542_imagePadding.odt differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index 88a703d..d3d8733 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -831,26 +831,39 @@ DECLARE_WW8EXPORT_TEST(testCharacterBorder, "charborder.odt")
     }
 }
 
+DECLARE_WW8EXPORT_TEST(testTdf41542_imagePadding, "tdf41542_imagePadding.odt")
+{
+    // borderlessImage - image WITHOUT BORDERS : simulate padding with -crop
+    text::GraphicCrop crop = getProperty<text::GraphicCrop>(getShape(2), "GraphicCrop");
+    CPPUNIT_ASSERT( crop.Left != 0 && crop.Right != 0 );
+    CPPUNIT_ASSERT( crop.Left == crop.Top && crop.Right == crop.Bottom && crop.Left == crop.Right );
+
+    // borderedImage - image WITH BORDERS : simulate padding with -crop
+    crop = getProperty<text::GraphicCrop>(getShape(3), "GraphicCrop");
+    CPPUNIT_ASSERT( crop.Left != 0 && crop.Right != 0 );
+    CPPUNIT_ASSERT( crop.Left == crop.Top && crop.Right == crop.Bottom && crop.Left == crop.Right );
+}
+
 DECLARE_WW8EXPORT_TEST(testFdo77454, "fdo77454.doc")
 {
     {
-        // check negative crops round-trip
+        // check negative crops round-trip  (with border/padding of 1)
         text::GraphicCrop const crop =
             getProperty<text::GraphicCrop>(getShape(1), "GraphicCrop");
-        CPPUNIT_ASSERT_EQUAL(sal_Int32( -439), crop.Left);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(-7040), crop.Right);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32( -220), crop.Top);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(-7040), crop.Bottom);
+        CPPUNIT_ASSERT(abs(sal_Int32( -439) - crop.Left)   <= 2);
+        CPPUNIT_ASSERT(abs(sal_Int32(-7040) - crop.Right)  <= 2);
+        CPPUNIT_ASSERT(abs(sal_Int32( -220) - crop.Top)    <= 2);
+        CPPUNIT_ASSERT(abs(sal_Int32(-7040) - crop.Bottom) <= 2);
     }
 
     {
-        // check positive crops round-trip
+        // check positive crops round-trip (with padding of 1)
         text::GraphicCrop const crop =
             getProperty<text::GraphicCrop>(getShape(2), "GraphicCrop");
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(  326), crop.Left);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32( 1208), crop.Right);
-        CPPUNIT_ASSERT(abs(sal_Int32(1635) -  crop.Top) <= 2);
-        CPPUNIT_ASSERT(abs(sal_Int32(  95) - crop.Bottom) <= 2);
+        CPPUNIT_ASSERT(abs(sal_Int32( 326) - crop.Left)   <= 3);
+        CPPUNIT_ASSERT(abs(sal_Int32(1208) - crop.Right)  <= 3);
+        CPPUNIT_ASSERT(abs(sal_Int32(1635) - crop.Top)    <= 3);
+        CPPUNIT_ASSERT(abs(sal_Int32(  95) - crop.Bottom) <= 3);
     }
 }
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 09e1172..2aea2cc 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4123,7 +4123,7 @@ void DocxAttributeOutput::DefaultStyle()
 /* Writes <a:srcRect> tag back to document.xml if a file conatins a cropped image.
 *  NOTE : Tested on images of type JPEG,EMF/WMF,BMP, PNG and GIF.
 */
-void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
+void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj, const SwFrameFormat* pFrameFormat )
 {
     uno::Reference< drawing::XShape > xShape( const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY );
     uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
@@ -4134,9 +4134,6 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
 
     Size aOriginalSize(aGrafObj.GetPrefSize());
 
-    css::text::GraphicCrop aGraphicCropStruct;
-    xPropSet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct;
-
     const MapMode aMap100mm( MapUnit::Map100thMM );
     const MapMode& rMapMode = aGrafObj.GetPrefMapMode();
     if (rMapMode.GetMapUnit() == MapUnit::MapPixel)
@@ -4144,15 +4141,33 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
         aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, aMap100mm);
     }
 
-    if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
+    css::text::GraphicCrop aGraphicCropStruct;
+    xPropSet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct;
+    sal_Int16 nCropL = aGraphicCropStruct.Left;
+    sal_Int16 nCropR = aGraphicCropStruct.Right;
+    sal_Int16 nCropT = aGraphicCropStruct.Top;
+    sal_Int16 nCropB = aGraphicCropStruct.Bottom;
+
+    // simulate border padding as a negative crop.
+    const SfxPoolItem* pItem;
+    if (pFrameFormat && SfxItemState::SET == pFrameFormat->GetItemState(RES_BOX, false, &pItem))
+    {
+        const SvxBoxItem& rBox = *static_cast<const SvxBoxItem*>(pItem);
+        nCropL -= rBox.GetDistance( SvxBoxItemLine::LEFT );
+        nCropR -= rBox.GetDistance( SvxBoxItemLine::RIGHT );
+        nCropT -= rBox.GetDistance( SvxBoxItemLine::TOP );
+        nCropB -= rBox.GetDistance( SvxBoxItemLine::BOTTOM );
+    }
+
+    if ( (0 != nCropL) || (0 != nCropT) || (0 != nCropR) || (0 != nCropB) )
     {
         double  widthMultiplier  = 100000.0/aOriginalSize.Width();
         double  heightMultiplier = 100000.0/aOriginalSize.Height();
 
-        double left   = aGraphicCropStruct.Left * widthMultiplier;
-        double right  = aGraphicCropStruct.Right * widthMultiplier;
-        double top    = aGraphicCropStruct.Top * heightMultiplier;
-        double bottom = aGraphicCropStruct.Bottom * heightMultiplier;
+        double left   = nCropL * widthMultiplier;
+        double right  = nCropR * widthMultiplier;
+        double top    = nCropT * heightMultiplier;
+        double bottom = nCropB * heightMultiplier;
 
         m_pSerializer->singleElementNS( XML_a, XML_srcRect,
              XML_l, I32S(left),
@@ -4347,7 +4362,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size
     m_pSerializer->endElementNS( XML_a, XML_blip );
 
     if (pSdrObj){
-        WriteSrcRect(pSdrObj);
+        WriteSrcRect(pSdrObj, pFrameFormat);
     }
 
     m_pSerializer->startElementNS( XML_a, XML_stretch,
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 18339f4..7c5149b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -410,7 +410,7 @@ private:
     ///
     /// @see WriteOLE2Obj()
     void FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrameFormat* pOLEFrameFormat, SwOLENode* pOLENode, const SdrObject* pSdrObj = nullptr);
-    void WriteSrcRect( const SdrObject* pSdrObj );
+    void WriteSrcRect( const SdrObject* pSdrObj, const SwFrameFormat* pFrameFormat );
     void WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat);
     bool WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize );
     bool WriteOLEMath( const SdrObject* pSdrObj, const SwOLENode& rNode, const Size& rSize );
diff --git a/sw/source/filter/ww8/escher.hxx b/sw/source/filter/ww8/escher.hxx
index fa2f30d..873486b 100644
--- a/sw/source/filter/ww8/escher.hxx
+++ b/sw/source/filter/ww8/escher.hxx
@@ -103,7 +103,7 @@ protected:
     void WriteOLEPicture(EscherPropertyContainer &rPropOpt,
         sal_uInt32 nShapeFlags, const Graphic &rGraphic, const SdrObject &rObj,
         sal_uInt32 nShapeId, const css::awt::Rectangle* pVisArea );
-    static void WriteGrfAttr(const SwNoTextNode& rNd,EscherPropertyContainer& rPropOpt);
+    static void WriteGrfAttr(const SwNoTextNode& rNd, const SwFrameFormat& rFormat, EscherPropertyContainer& rPropOpt);
 
     sal_Int32 DrawModelToEmu(sal_Int32 nVal) const
         { return BigMulDiv(nVal, mnEmuMul, mnEmuDiv); }
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index d5d0d2d..24c2583 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -1732,7 +1732,7 @@ sal_Int32 SwBasicEscherEx::WriteGrfFlyFrame(const SwFrameFormat& rFormat, sal_uI
 
     aPropOpt.AddOpt( ESCHER_Prop_pibFlags, nFlags );
     nBorderThick = WriteFlyFrameAttr(rFormat,mso_sptPictureFrame,aPropOpt);
-    WriteGrfAttr(*pGrfNd, aPropOpt);
+    WriteGrfAttr(*pGrfNd, rFormat, aPropOpt);
 
     aPropOpt.Commit( GetStream() );
 
@@ -1743,7 +1743,7 @@ sal_Int32 SwBasicEscherEx::WriteGrfFlyFrame(const SwFrameFormat& rFormat, sal_uI
     return nBorderThick;
 }
 
-void SwBasicEscherEx::WriteGrfAttr(const SwNoTextNode& rNd,
+void SwBasicEscherEx::WriteGrfAttr(const SwNoTextNode& rNd, const SwFrameFormat& rFormat,
     EscherPropertyContainer& rPropOpt)
 {
     const SfxPoolItem* pItem;
@@ -1814,20 +1814,39 @@ void SwBasicEscherEx::WriteGrfAttr(const SwNoTextNode& rNd,
     if (nBrightness != 0)
         rPropOpt.AddOpt( ESCHER_Prop_pictureBrightness, nBrightness * 327 );
 
+    sal_Int32 nCropL = 0;
+    sal_Int32 nCropR = 0;
+    sal_Int32 nCropT = 0;
+    sal_Int32 nCropB = 0;
     if (SfxItemState::SET == rNd.GetSwAttrSet().GetItemState(RES_GRFATR_CROPGRF,
         true, &pItem))
     {
-        const Size aSz( rNd.GetTwipSize() );
-        sal_Int32 nVal;
-        if( 0 != ( nVal = static_cast<const SwCropGrf*>(pItem )->GetLeft() ) )
-            rPropOpt.AddOpt( ESCHER_Prop_cropFromLeft, ToFract16( nVal, aSz.Width()) );
-        if( 0 != ( nVal = static_cast<const SwCropGrf*>(pItem )->GetRight() ) )
-            rPropOpt.AddOpt( ESCHER_Prop_cropFromRight, ToFract16( nVal, aSz.Width()));
-        if( 0 != ( nVal = static_cast<const SwCropGrf*>(pItem )->GetTop() ) )
-            rPropOpt.AddOpt( ESCHER_Prop_cropFromTop, ToFract16( nVal, aSz.Height()));
-        if( 0 != ( nVal = static_cast<const SwCropGrf*>(pItem )->GetBottom() ) )
-            rPropOpt.AddOpt( ESCHER_Prop_cropFromBottom, ToFract16( nVal, aSz.Height()));
+        const SwCropGrf& rCrop = *static_cast<const SwCropGrf*>(pItem);
+        nCropL += rCrop.GetLeft();
+        nCropR += rCrop.GetRight();
+        nCropT += rCrop.GetTop();
+        nCropB += rCrop.GetBottom();
     }
+
+    // simulate border padding as a negative crop.
+    if (SfxItemState::SET == rFormat.GetItemState(RES_BOX, false, &pItem))
+    {
+        const SvxBoxItem& rBox = *static_cast<const SvxBoxItem*>(pItem);
+        nCropL -= rBox.GetDistance( SvxBoxItemLine::LEFT );
+        nCropR -= rBox.GetDistance( SvxBoxItemLine::RIGHT );
+        nCropT -= rBox.GetDistance( SvxBoxItemLine::TOP );
+        nCropB -= rBox.GetDistance( SvxBoxItemLine::BOTTOM );
+    }
+
+    const Size aSz( rNd.GetTwipSize() );
+    if( 0 != nCropL )
+        rPropOpt.AddOpt( ESCHER_Prop_cropFromLeft, ToFract16( nCropL, aSz.Width()) );
+    if( 0 != nCropR )
+        rPropOpt.AddOpt( ESCHER_Prop_cropFromRight, ToFract16( nCropR, aSz.Width()));
+    if( 0 != nCropT )
+        rPropOpt.AddOpt( ESCHER_Prop_cropFromTop, ToFract16( nCropT, aSz.Height()));
+    if( 0 != nCropB )
+        rPropOpt.AddOpt( ESCHER_Prop_cropFromBottom, ToFract16( nCropB, aSz.Height()));
 }
 
 void SwBasicEscherEx::SetPicId(const SdrObject &, sal_uInt32,
@@ -1891,7 +1910,7 @@ sal_Int32 SwBasicEscherEx::WriteOLEFlyFrame(const SwFrameFormat& rFormat, sal_uI
             rMirror), pGraphic ? *pGraphic : Graphic(), *pSdrObj, nShapeId, bRectIsSet ? &aRect : nullptr );
 
         nBorderThick = WriteFlyFrameAttr(rFormat, mso_sptPictureFrame, aPropOpt);
-        WriteGrfAttr(rOLENd, aPropOpt);
+        WriteGrfAttr(rOLENd, rFormat, aPropOpt);
         aPropOpt.Commit(GetStream());
 
         // store anchor attribute


More information about the Libreoffice-commits mailing list