summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGülşah Köse <gulsah.kose@collabora.com>2021-02-01 17:03:33 +0300
committerGülşah Köse <gulsah.kose@collabora.com>2021-02-10 07:04:38 +0100
commitccdee8eebaa56619248e35001017226eecfe4e83 (patch)
tree708db8ed2f0e37e9709b553b4a04de6c51a60aab
parente4e0cf825a858e82c299c55632b03ca6f80647d1 (diff)
tdf#134210 Import crop position of bitmap filled shape.
Change-Id: I6a62d68cd0f57e53934851a2f53dae05bf7d3730 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110262 Tested-by: Jenkins Reviewed-by: Gülşah Köse <gulsah.kose@collabora.com>
-rw-r--r--oox/source/drawingml/fillproperties.cxx84
-rw-r--r--oox/source/export/drawingml.cxx39
-rw-r--r--sd/qa/unit/data/pptx/crop-position.pptxbin0 -> 175724 bytes
-rw-r--r--sd/qa/unit/export-tests-ooxml1.cxx29
-rw-r--r--sd/qa/unit/import-tests.cxx16
5 files changed, 129 insertions, 39 deletions
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx
index 6d537097a206..6feeb1c9991d 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -87,6 +87,30 @@ Reference< XGraphic > lclRotateGraphic(uno::Reference<graphic::XGraphic> const &
return aReturnGraphic.GetXGraphic();
}
+void lclCalculateCropPercentage(uno::Reference<graphic::XGraphic> const & xGraphic, geometry::IntegerRectangle2D &aFillRect)
+{
+ ::Graphic aGraphic(xGraphic);
+ assert (aGraphic.GetType() == GraphicType::Bitmap);
+
+ BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
+
+ sal_Int32 nScaledWidth = aBitmapEx.GetSizePixel().Width();
+ sal_Int32 nScaledHeight = aBitmapEx.GetSizePixel().Height();
+
+ sal_Int32 nOrigWidth = (nScaledWidth * (100000 - aFillRect.X1 - aFillRect.X2)) / 100000;
+ sal_Int32 nOrigHeight = (nScaledHeight * (100000 - aFillRect.Y1 - aFillRect.Y2)) / 100000;
+
+ sal_Int32 nLeftPercentage = nScaledWidth * aFillRect.X1 / nOrigWidth;
+ sal_Int32 nRightPercentage = nScaledWidth * aFillRect.X2 / nOrigWidth;
+ sal_Int32 nTopPercentage = nScaledHeight * aFillRect.Y1 / nOrigHeight;
+ sal_Int32 nBottomPercentage = nScaledHeight * aFillRect.Y2 / nOrigHeight;
+
+ aFillRect.X1 = -nLeftPercentage;
+ aFillRect.X2 = -nRightPercentage;
+ aFillRect.Y1 = -nTopPercentage;
+ aFillRect.Y2 = -nBottomPercentage;
+}
+
Reference< XGraphic > lclCropGraphic(uno::Reference<graphic::XGraphic> const & xGraphic, geometry::IntegerRectangle2D aFillRect)
{
::Graphic aGraphic(xGraphic);
@@ -103,8 +127,15 @@ Reference< XGraphic > lclCropGraphic(uno::Reference<graphic::XGraphic> const & x
sal_Int32 nBottomCorr = nOrigHeight * -1 * static_cast<double>(aFillRect.Y2) / 100000;
nHeight += nBottomCorr;
- aBitmapEx.Scale(Size(aBitmapEx.GetSizePixel().Width(), nHeight));
- aBitmapEx.Crop(tools::Rectangle(Point(0, nTopCorr), Size(aBitmapEx.GetSizePixel().Width(), nOrigHeight)));
+ sal_Int32 nOrigWidth = aBitmapEx.GetSizePixel().Width();
+ sal_Int32 nWidth = nOrigWidth;
+ sal_Int32 nLeftCorr = nOrigWidth * -1 * static_cast<double>(aFillRect.X1) / 100000;
+ nWidth += nLeftCorr;
+ sal_Int32 nRightCorr = nOrigWidth * -1 * static_cast<double>(aFillRect.X2) / 100000;
+ nWidth += nRightCorr;
+
+ aBitmapEx.Scale(Size(nWidth, nHeight));
+ aBitmapEx.Crop(tools::Rectangle(Point(nLeftCorr, nTopCorr), Size(nOrigWidth, nOrigHeight)));
aReturnGraphic = ::Graphic(aBitmapEx);
aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
@@ -819,6 +850,36 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe
nContrast = 0;
}
+ // cropping
+ if ( maBlipProps.moClipRect.has() )
+ {
+ geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.get() );
+ awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
+ if ( aOriginalSize.Width && aOriginalSize.Height )
+ {
+ text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
+ if ( oClipRect.X1 )
+ aGraphCrop.Left = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
+ if ( oClipRect.Y1 )
+ aGraphCrop.Top = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
+ if ( oClipRect.X2 )
+ aGraphCrop.Right = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
+ if ( oClipRect.Y2 )
+ aGraphCrop.Bottom = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
+ rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
+ }
+
+ if(mbIsCustomShape)
+ {
+ geometry::IntegerRectangle2D aCropRect = oClipRect;
+ lclCalculateCropPercentage(xGraphic, aCropRect);
+ xGraphic = lclCropGraphic(xGraphic, aCropRect);
+
+ rPropMap.setProperty(PROP_FillBitmap, xGraphic);
+ }
+
+ }
+
if(mbIsCustomShape)
{
// it is a cropped graphic.
@@ -843,25 +904,6 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe
else
rPropMap.setProperty(PROP_Graphic, xGraphic);
- // cropping
- if ( maBlipProps.moClipRect.has() )
- {
- geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.get() );
- awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
- if ( aOriginalSize.Width && aOriginalSize.Height )
- {
- text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
- if ( oClipRect.X1 )
- aGraphCrop.Left = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
- if ( oClipRect.Y1 )
- aGraphCrop.Top = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
- if ( oClipRect.X2 )
- aGraphCrop.Right = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
- if ( oClipRect.Y2 )
- aGraphCrop.Bottom = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
- rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
- }
- }
if ( maBlipProps.moAlphaModFix.has() )
{
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 486fb90bd3ec..e2f0602017b6 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1606,27 +1606,40 @@ void DrawingML::WritePattFill(const Reference<XPropertySet>& rXPropSet, const cs
mpFS->endElementNS( XML_a , XML_pattFill );
}
-void DrawingML::WriteGraphicCropProperties(uno::Reference<beans::XPropertySet> const & rXPropSet, Size const & rOriginalSize, MapMode const & rMapMode)
+void DrawingML::WriteGraphicCropProperties(uno::Reference<beans::XPropertySet> const & rXPropSet,
+ Size const & rOriginalSize,
+ MapMode const & rMapMode)
{
if (!GetProperty(rXPropSet, "GraphicCrop"))
return;
- Size aOriginalSize(rOriginalSize);
-
- // GraphicCrop is in mm100, so in case the original size is in pixels, convert it over.
- if (rMapMode.GetMapUnit() == MapUnit::MapPixel)
- aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, MapMode(MapUnit::Map100thMM));
-
css::text::GraphicCrop aGraphicCropStruct;
mAny >>= aGraphicCropStruct;
- if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
+ if(GetProperty(rXPropSet, "CustomShapeGeometry"))
+ {
+ // tdf#134210 GraphicCrop property is handled in import filter because of LibreOffice has not core
+ // feature. We croped the bitmap physically and MSO shouldn't crop bitmap one more time. When we
+ // have core feature for graphic cropping in custom shapes, we should uncomment the code anymore.
+
+ mpFS->singleElementNS( XML_a, XML_srcRect);
+ }
+ else
{
- mpFS->singleElementNS( XML_a, XML_srcRect,
- XML_l, OString::number(rtl::math::round(aGraphicCropStruct.Left * 100000.0 / aOriginalSize.Width())),
- XML_t, OString::number(rtl::math::round(aGraphicCropStruct.Top * 100000.0 / aOriginalSize.Height())),
- XML_r, OString::number(rtl::math::round(aGraphicCropStruct.Right * 100000.0 / aOriginalSize.Width())),
- XML_b, OString::number(rtl::math::round(aGraphicCropStruct.Bottom * 100000.0 / aOriginalSize.Height())) );
+ Size aOriginalSize(rOriginalSize);
+
+ // GraphicCrop is in mm100, so in case the original size is in pixels, convert it over.
+ if (rMapMode.GetMapUnit() == MapUnit::MapPixel)
+ aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, MapMode(MapUnit::Map100thMM));
+
+ if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
+ {
+ mpFS->singleElementNS( XML_a, XML_srcRect,
+ XML_l, OString::number(rtl::math::round(aGraphicCropStruct.Left * 100000.0 / aOriginalSize.Width())),
+ XML_t, OString::number(rtl::math::round(aGraphicCropStruct.Top * 100000.0 / aOriginalSize.Height())),
+ XML_r, OString::number(rtl::math::round(aGraphicCropStruct.Right * 100000.0 / aOriginalSize.Width())),
+ XML_b, OString::number(rtl::math::round(aGraphicCropStruct.Bottom * 100000.0 / aOriginalSize.Height())) );
+ }
}
}
diff --git a/sd/qa/unit/data/pptx/crop-position.pptx b/sd/qa/unit/data/pptx/crop-position.pptx
new file mode 100644
index 000000000000..69507514e0b7
--- /dev/null
+++ b/sd/qa/unit/data/pptx/crop-position.pptx
Binary files differ
diff --git a/sd/qa/unit/export-tests-ooxml1.cxx b/sd/qa/unit/export-tests-ooxml1.cxx
index da61677f7b48..a134e699d3fa 100644
--- a/sd/qa/unit/export-tests-ooxml1.cxx
+++ b/sd/qa/unit/export-tests-ooxml1.cxx
@@ -1152,17 +1152,36 @@ void SdOOXMLExportTest1::testCustomshapeBitmapfillSrcrect()
xDocShRef->DoClose();
xmlDocUniquePtr pXmlDoc = parseExport(tempFile, "ppt/slides/slide1.xml");
- const OString sXmlPath = "//a:blipFill/a:srcRect";
+
+ // tdf#132680
+ // We are preventing the side effect of DOCX improvement to PPTX case.
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 1
// - Actual : 0
// - XPath '//a:blipFill/a:srcRect' number of nodes is incorrect
// i.e. <a:srcRect> was exported as <a:fillRect> in <a:stretch>, which made part of the image
// invisible.
- double fLeftPercent = std::round(getXPath(pXmlDoc, sXmlPath, "l").toDouble() / 1000);
- CPPUNIT_ASSERT_EQUAL(4.0, fLeftPercent);
- double fRightPercent = std::round(getXPath(pXmlDoc, sXmlPath, "r").toDouble() / 1000);
- CPPUNIT_ASSERT_EQUAL(4.0, fRightPercent);
+
+ // tdf#134210
+ // Original values of attribute of l and r in xml files: <a:srcRect l="4393" r="4393"/>
+ // Because of we have not core feature for cropping bitmap in custom shapes, we added cropping
+ // support to import filter. We modified the bitmap during import. As result the original
+ // image is cropped anymore (if we had the core feature for that, the original image would
+ // remain same, just we would see like cropped in the shape) To see the image in correct
+ // position in Microsoft Office too, we have to remove left right top bottom percentages
+ // anymore. In the future if we add core feature to LibreOffice, this test will failed with
+ // When we add the core feature, we should change the control value with 4393 as following.
+
+ //const OString sXmlPath = "//a:blipFill/a:srcRect";
+ //sal_Int32 nLeftPercent = getXPath(pXmlDoc, sXmlPath, "l").toInt32();
+ //CPPUNIT_ASSERT_EQUAL(sal_Int32(4393), nLeftPercent);
+ //sal_Int32 nRightPercent = getXPath(pXmlDoc, sXmlPath, "r").toInt32();
+ //CPPUNIT_ASSERT_EQUAL(sal_Int32(4393), nRightPercent);
+
+ assertXPathNoAttribute(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:blipFill/a:srcRect", "l");
+ assertXPathNoAttribute(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:blipFill/a:srcRect", "r");
+ assertXPathNoAttribute(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:blipFill/a:srcRect", "t");
+ assertXPathNoAttribute(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:blipFill/a:srcRect", "b");
}
void SdOOXMLExportTest1::testTdf100348FontworkBitmapFill()
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index de361058bfb3..8af1b3000e9b 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -213,6 +213,7 @@ public:
void testShapeGlowEffectPPTXImpoer();
void testShapeBlurPPTXImport();
void testMirroredGraphic();
+ void testCropPositionGraphic();
bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected);
void testPatternImport();
@@ -342,6 +343,7 @@ public:
CPPUNIT_TEST(testShapeGlowEffectPPTXImpoer);
CPPUNIT_TEST(testShapeBlurPPTXImport);
CPPUNIT_TEST(testMirroredGraphic);
+ CPPUNIT_TEST(testCropPositionGraphic);
CPPUNIT_TEST_SUITE_END();
};
@@ -3321,6 +3323,20 @@ void SdImportTest::testMirroredGraphic()
xDocShRef->DoClose();
}
+void SdImportTest::testCropPositionGraphic()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc(u"sd/qa/unit/data/pptx/crop-position.pptx"), PPTX);
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xShape.is());
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xShape->getPropertyValue("FillBitmap") >>= xGraphic;
+ CPPUNIT_ASSERT(xGraphic.is());
+ Graphic aGraphic(xGraphic);
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ CPPUNIT_ASSERT_EQUAL( Color(8682893), aBitmap.GetPixelColor( 0, 0 ));
+ xDocShRef->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
CPPUNIT_PLUGIN_IMPLEMENT();