summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2016-11-04 21:32:38 +0300
committerJustin Luth <justin_luth@sil.org>2016-11-07 04:09:41 +0000
commit8eff1decd91cbfb10094c25d4cf1d2b434a4da72 (patch)
treebcc51a30d8eaa4acbaff628dabff996c2273779f /sw
parentbc6017d66fcf37db1f632a3ce667f4c3bf9d1d02 (diff)
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@libreoffice.org> Reviewed-by: Justin Luth <justin_luth@sil.org>
Diffstat (limited to 'sw')
-rwxr-xr-xsw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odtbin0 -> 17926 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport3.cxx13
-rwxr-xr-xsw/qa/extras/ww8export/data/tdf41542_imagePadding.odtbin0 -> 17926 bytes
-rw-r--r--sw/qa/extras/ww8export/ww8export.cxx33
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx35
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx2
-rw-r--r--sw/source/filter/ww8/escher.hxx2
-rw-r--r--sw/source/filter/ww8/wrtw8esh.cxx45
8 files changed, 95 insertions, 35 deletions
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 000000000000..019e19f247e1
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf41542_imagePadding.odt
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index 4d73a7f62ee9..f93ace6ad4c3 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 000000000000..019e19f247e1
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf41542_imagePadding.odt
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index 88a703d99782..d3d87332f48e 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 09e117215169..2aea2cc1ee54 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 18339f453514..7c5149be2ff8 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 fa2f30dba168..873486be7a29 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 d5d0d2de844f..24c2583314d0 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