tdf#151844 Make EMR_EXTSELECTCLIPRGN factor in WinOrg coordinates
EMR_EXTSELECTCLIPRGN would not factor in WinOrg coordinates which would
give the clip box wrong coordinates causing some graphics to look
chopped in the wrong way.
Change-Id: I4f9a1b1c27fc276d188d0d865991795dab48dce5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142110
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx
index 997f228..b4fd639 100644
--- a/emfio/inc/mtftools.hxx
+++ b/emfio/inc/mtftools.hxx
@@ -731,6 +731,7 @@ namespace emfio
void ScaleDevExt(double fX, double fY);
void SetWinOrg(const Point& rPoint, bool bIsEMF = false);
Point GetWinOrg() { return Point(mnWinOrgX, mnWinOrgY); }
void SetWinOrgOffset(sal_Int32 nX, sal_Int32 nY);
void SetWinExt(const Size& rSize, bool bIsEMF = false);
void ScaleWinExt(double fX, double fY);
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 99adda3..75f2b900 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -69,6 +69,7 @@ class Test : public UnoApiXmlTest
void TestEmfPlusDrawPathWithMiterLimit();
void TestEmfPlusFillClosedCurve();
void TestExtTextOutOpaqueAndClipTransform();
void TestNegativeWinOrg();
void TestBitBltStretchBltWMF();
void TestExtTextOutOpaqueAndClipWMF();
@@ -122,6 +123,7 @@ public:
CPPUNIT_TEST(TestEmfPlusDrawPathWithMiterLimit);
CPPUNIT_TEST(TestEmfPlusFillClosedCurve);
CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform);
CPPUNIT_TEST(TestNegativeWinOrg);
CPPUNIT_TEST(TestBitBltStretchBltWMF);
CPPUNIT_TEST(TestExtTextOutOpaqueAndClipWMF);
@@ -1203,6 +1205,24 @@ void Test::TestExtTextOutOpaqueAndClipTransform()
"#000000");
}
void Test::TestNegativeWinOrg()
{
Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestNegativeWinOrg.emf");
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
drawinglayer::Primitive2dXmlDump dumper;
xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
CPPUNIT_ASSERT(pDocument);
// The crop box (EMR_EXTSELECTCLIPRGN) would not factor in WinOrg coordinates
// and be lower and more to the right than it actually is which would cut the
// text in the emf above in half.
assertXPath(pDocument, aXPathPrefix + "mask/group[1]/mask/polypolygon", 1);
assertXPath(pDocument, aXPathPrefix + "mask/group[1]/mask/polypolygon", "minx", "0");
assertXPath(pDocument, aXPathPrefix + "mask/group[1]/mask/polypolygon", "miny", "272");
assertXPath(pDocument, aXPathPrefix + "mask/group[1]/mask/polypolygon", "maxx", "6800");
assertXPath(pDocument, aXPathPrefix + "mask/group[1]/mask/polypolygon", "maxy", "644");
}
void Test::TestBitBltStretchBltWMF()
{
// tdf#55058 tdf#142722 WMF records: BITBLT, STRETCHBLT.
diff --git a/emfio/qa/cppunit/emf/data/TestNegativeWinOrg.emf b/emfio/qa/cppunit/emf/data/TestNegativeWinOrg.emf
new file mode 100644
index 0000000..d428f4c
--- /dev/null
+++ b/emfio/qa/cppunit/emf/data/TestNegativeWinOrg.emf
Binary files differ
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 7baa7c8..207d837 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -332,7 +332,7 @@ SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun)
return rInStream;
}
bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen )
bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen, Point aWinOrg )
{
if (nLen < 32) // 32 bytes - Size of RegionDataHeader
return false;
@@ -369,6 +369,10 @@ bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_
rStream.ReadInt32(nTop);
rStream.ReadInt32(nRight);
rStream.ReadInt32(nBottom);
nLeft += aWinOrg.X();
nRight += aWinOrg.X();
nTop += aWinOrg.Y();
nBottom += aWinOrg.Y();
rPolyPoly.append( basegfx::utils::createPolygonFromRect( ::basegfx::B2DRectangle( nLeft, nTop, nRight, nBottom ) ) );
SAL_INFO("emfio", "\t\t" << i << " Left: " << nLeft << ", top: " << nTop << ", right: " << nRight << ", bottom: " << nBottom);
}
@@ -1348,7 +1352,7 @@ namespace emfio
{
basegfx::B2DPolyPolygon aPolyPoly;
if (cbRgnData)
ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize);
ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg());
const tools::PolyPolygon aPolyPolygon(aPolyPoly);
SetClipPath(aPolyPolygon, static_cast<RegionMode>(nClippingMode), false);
}
@@ -1930,7 +1934,7 @@ namespace emfio
mpInputStream->ReadUInt32( nRgnDataSize ).ReadUInt32( nIndex );
nRemainingRecSize -= 24;
if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize))
if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg()))
{
Push();
SelectObject( nIndex );
@@ -1955,7 +1959,7 @@ namespace emfio
mpInputStream->ReadUInt32( nRgnDataSize );
nRemainingRecSize -= 20;
if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize))
if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg()))
{
tools::PolyPolygon aPolyPolygon(aPolyPoly);
DrawPolyPolygon( aPolyPolygon );