diff options
-rw-r--r-- | drawinglayer/source/tools/emfphelperdata.cxx | 180 | ||||
-rw-r--r-- | drawinglayer/source/tools/emfphelperdata.hxx | 3 | ||||
-rw-r--r-- | emfio/qa/cppunit/emf/EmfImportTest.cxx | 66 | ||||
-rw-r--r-- | emfio/qa/cppunit/emf/data/TestEmfPlusGetDC.emf | bin | 0 -> 23856 bytes | |||
-rw-r--r-- | emfio/qa/cppunit/emf/data/TestEmfPlusSave.emf | bin | 0 -> 1140 bytes |
5 files changed, 184 insertions, 65 deletions
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 447686167837..e60f8815ef79 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -486,18 +486,32 @@ namespace emfplushelper map[ index ] = state; } - void EmfPlusHelperData::GraphicStatePop(GraphicStateMap& map, sal_Int32 index, wmfemfhelper::PropertyHolder& rState) + void EmfPlusHelperData::GraphicStatePop(GraphicStateMap& map, sal_Int32 index) { - GraphicStateMap::iterator iter = map.find( index ); + GraphicStateMap::iterator iter = map.find(index); - if ( iter != map.end() ) + if (iter != map.end()) { wmfemfhelper::PropertyHolder state = iter->second; maWorldTransform = state.getTransformation(); - rState.setClipPolyPolygon( state.getClipPolyPolygon() ); + if (state.getClipPolyPolygonActive()) + { + SAL_INFO("drawinglayer.emf", + "EMF+\t Restore clipping region to saved in index: " << index); + wmfemfhelper::HandleNewClipRegion(state.getClipPolyPolygon(), mrTargetHolders, + mrPropertyHolders); + } + else + { + SAL_INFO("drawinglayer.emf", "EMF+\t Disable clipping"); + wmfemfhelper::HandleNewClipRegion(::basegfx::B2DPolyPolygon(), mrTargetHolders, + mrPropertyHolders); + } mappingChanged(); - SAL_INFO("drawinglayer.emf", "EMF+\t\tStack index: " << index << " found, maWorldTransform: " << maWorldTransform); + SAL_INFO("drawinglayer.emf", + "EMF+\t\tStack index: " << index + << " found, maWorldTransform: " << maWorldTransform); } } @@ -1000,14 +1014,8 @@ namespace emfplushelper } case EmfPlusCombineModeIntersect: { - if (leftPolygon.count()) - { - aClippedPolyPolygon = basegfx::utils::clipPolyPolygonOnPolyPolygon( - leftPolygon, - rightPolygon, - true, - false); - } + aClippedPolyPolygon = basegfx::utils::clipPolyPolygonOnPolyPolygon( + leftPolygon, rightPolygon, true, false); break; } case EmfPlusCombineModeUnion: @@ -1080,8 +1088,18 @@ namespace emfplushelper if (bIsGetDCProcessing) { - SAL_INFO("drawinglayer.emf", "EMF+\t reset the current clipping region for the world space to infinity."); - wmfemfhelper::HandleNewClipRegion(::basegfx::B2DPolyPolygon(), mrTargetHolders, mrPropertyHolders); + if (aGetDCState.getClipPolyPolygonActive()) + { + SAL_INFO("drawinglayer.emf", "EMF+\t Restore region to GetDC saved"); + wmfemfhelper::HandleNewClipRegion(aGetDCState.getClipPolyPolygon(), mrTargetHolders, + mrPropertyHolders); + } + else + { + SAL_INFO("drawinglayer.emf", "EMF+\t Disable clipping"); + wmfemfhelper::HandleNewClipRegion(::basegfx::B2DPolyPolygon(), mrTargetHolders, + mrPropertyHolders); + } bIsGetDCProcessing = false; } if (type == EmfPlusRecordTypeObject && ((mbMultipart && (flags & 0x7fff) == (mMFlags & 0x7fff)) || (flags & 0x8000))) @@ -1160,6 +1178,7 @@ namespace emfplushelper case EmfPlusRecordTypeGetDC: { bIsGetDCProcessing = true; + aGetDCState = mrPropertyHolders.Current(); SAL_INFO("drawinglayer.emf", "EMF+\tAlready used in svtools wmf/emf filter parser"); break; } @@ -1819,7 +1838,7 @@ namespace emfplushelper rMS.ReadUInt32(stackIndex); SAL_INFO("drawinglayer.emf", "EMF+\t Restore stack index: " << stackIndex); - GraphicStatePop(mGSStack, stackIndex, mrPropertyHolders.Current()); + GraphicStatePop(mGSStack, stackIndex); break; } case EmfPlusRecordTypeBeginContainer: @@ -1866,7 +1885,7 @@ namespace emfplushelper rMS.ReadUInt32(stackIndex); SAL_INFO("drawinglayer.emf", "EMF+\t End Container stack index: " << stackIndex); - GraphicStatePop(mGSContainerStack, stackIndex, mrPropertyHolders.Current()); + GraphicStatePop(mGSContainerStack, stackIndex); break; } case EmfPlusRecordTypeSetWorldTransform: @@ -2001,62 +2020,95 @@ namespace emfplushelper break; } case EmfPlusRecordTypeSetClipRect: - { - int combineMode = (flags >> 8) & 0xf; - - SAL_INFO("drawinglayer.emf", "EMF+\t SetClipRect combine mode: " << combineMode); - - float dx, dy, dw, dh; - ReadRectangle(rMS, dx, dy, dw, dh); - SAL_INFO("drawinglayer.emf", "EMF+\t RectData: " << dx << "," << dy << " " << dw << "x" << dh); - ::basegfx::B2DPoint mappedPoint1(Map(dx, dy)); - ::basegfx::B2DPoint mappedPoint2(Map(dx + dw, dy + dh)); - - ::basegfx::B2DPolyPolygon polyPolygon( - ::basegfx::utils::createPolygonFromRect( - ::basegfx::B2DRectangle( - mappedPoint1.getX(), - mappedPoint1.getY(), - mappedPoint2.getX(), - mappedPoint2.getY()))); - - HandleNewClipRegion(combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), - combineMode, polyPolygon), mrTargetHolders, mrPropertyHolders); - break; - } case EmfPlusRecordTypeSetClipPath: + case EmfPlusRecordTypeSetClipRegion: { int combineMode = (flags >> 8) & 0xf; - SAL_INFO("drawinglayer.emf", "EMF+\t SetClipPath combine mode: " << combineMode); - SAL_INFO("drawinglayer.emf", "EMF+\t Path in slot: " << (flags & 0xff)); - - EMFPPath *path = dynamic_cast<EMFPPath*>(maEMFPObjects[flags & 0xff].get()); - if (!path) + ::basegfx::B2DPolyPolygon polyPolygon; + if (type == EmfPlusRecordTypeSetClipRect) { - SAL_WARN("drawinglayer.emf", "EMF+\t TODO Unable to find path in slot: " << (flags & 0xff)); - break; - } + SAL_INFO("drawinglayer.emf", "EMF+\t SetClipRect"); - ::basegfx::B2DPolyPolygon& clipPoly(path->GetPolygon(*this)); + float dx, dy, dw, dh; + ReadRectangle(rMS, dx, dy, dw, dh); + SAL_INFO("drawinglayer.emf", + "EMF+\t RectData: " << dx << "," << dy << " " << dw << "x" << dh); + ::basegfx::B2DPoint mappedPoint1(Map(dx, dy)); + ::basegfx::B2DPoint mappedPoint2(Map(dx + dw, dy + dh)); + + polyPolygon + = ::basegfx::B2DPolyPolygon(::basegfx::utils::createPolygonFromRect( + ::basegfx::B2DRectangle(mappedPoint1.getX(), mappedPoint1.getY(), + mappedPoint2.getX(), mappedPoint2.getY()))); + } + else if (type == EmfPlusRecordTypeSetClipPath) + { + SAL_INFO("drawinglayer.emf", "EMF+\tSetClipPath " << (flags & 0xff)); - HandleNewClipRegion(combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), - combineMode, clipPoly), mrTargetHolders, mrPropertyHolders); - break; - } - case EmfPlusRecordTypeSetClipRegion: - { - int combineMode = (flags >> 8) & 0xf; - SAL_INFO("drawinglayer.emf", "EMF+\t Region in slot: " << (flags & 0xff)); + EMFPPath* path = dynamic_cast<EMFPPath*>(maEMFPObjects[flags & 0xff].get()); + if (!path) + { + SAL_WARN("drawinglayer.emf", + "EMF+\t TODO Unable to find path in slot: " << (flags & 0xff)); + break; + } + polyPolygon = path->GetPolygon(*this); + } + else if (type == EmfPlusRecordTypeSetClipRegion) + { + SAL_INFO("drawinglayer.emf", "EMF+\t Region in slot: " << (flags & 0xff)); + EMFPRegion* region + = dynamic_cast<EMFPRegion*>(maEMFPObjects[flags & 0xff].get()); + if (!region) + { + SAL_WARN( + "drawinglayer.emf", + "EMF+\t TODO Unable to find region in slot: " << (flags & 0xff)); + break; + } + polyPolygon = region->regionPolyPolygon; + } SAL_INFO("drawinglayer.emf", "EMF+\t Combine mode: " << combineMode); - EMFPRegion *region = dynamic_cast<EMFPRegion*>(maEMFPObjects[flags & 0xff].get()); - if (!region) + ::basegfx::B2DPolyPolygon aClippedPolyPolygon; + if (mrPropertyHolders.Current().getClipPolyPolygonActive()) { - SAL_WARN("drawinglayer.emf", "EMF+\t TODO Unable to find region in slot: " << (flags & 0xff)); - break; + aClippedPolyPolygon + = combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), + combineMode, polyPolygon); } - - HandleNewClipRegion(combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), - combineMode, region->regionPolyPolygon), mrTargetHolders, mrPropertyHolders); + else + { + //Combine with infinity + switch (combineMode) + { + case EmfPlusCombineModeReplace: + case EmfPlusCombineModeIntersect: + { + aClippedPolyPolygon = polyPolygon; + break; + } + case EmfPlusCombineModeUnion: + { + // Disable clipping as the clipping is infinity + aClippedPolyPolygon = ::basegfx::B2DPolyPolygon(); + break; + } + case EmfPlusCombineModeXOR: + case EmfPlusCombineModeComplement: + { + //TODO It is not correct and it should be fixed + aClippedPolyPolygon = polyPolygon; + break; + } + case EmfPlusCombineModeExclude: + { + //TODO It is not correct and it should be fixed + aClippedPolyPolygon = ::basegfx::B2DPolyPolygon(); + break; + } + } + } + HandleNewClipRegion(aClippedPolyPolygon, mrTargetHolders, mrPropertyHolders); break; } case EmfPlusRecordTypeOffsetClip: diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx index cf3474b5b1a7..563f7773c3ba 100644 --- a/drawinglayer/source/tools/emfphelperdata.hxx +++ b/drawinglayer/source/tools/emfphelperdata.hxx @@ -213,6 +213,7 @@ namespace emfplushelper /// data holders wmfemfhelper::TargetHolders& mrTargetHolders; wmfemfhelper::PropertyHolders& mrPropertyHolders; + wmfemfhelper::PropertyHolder aGetDCState; bool bIsGetDCProcessing; // readers @@ -224,7 +225,7 @@ namespace emfplushelper // stack actions void GraphicStatePush(GraphicStateMap& map, sal_Int32 index); - void GraphicStatePop (GraphicStateMap& map, sal_Int32 index, wmfemfhelper::PropertyHolder& rState); + void GraphicStatePop(GraphicStateMap& map, sal_Int32 index); // primitive creators void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index fce8961a849a..0f2816962a91 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -63,6 +63,8 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest: void TestSetArcDirection(); void TestDrawPolyLine16WithClip(); void TestFillRegion(); + void TestEmfPlusGetDC(); + void TestEmfPlusSave(); void TestExtTextOutOpaqueAndClipTransform(); void TestBitBltStretchBltWMF(); @@ -106,6 +108,8 @@ public: CPPUNIT_TEST(TestSetArcDirection); CPPUNIT_TEST(TestDrawPolyLine16WithClip); CPPUNIT_TEST(TestFillRegion); + CPPUNIT_TEST(TestEmfPlusGetDC); + CPPUNIT_TEST(TestEmfPlusSave); CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform); CPPUNIT_TEST(TestBitBltStretchBltWMF); @@ -828,6 +832,68 @@ void Test::TestPolylinetoCloseStroke() assertXPath(pDocument, aXPathPrefix + "polygonhairline[2]", "color", "#000000"); } +void Test::TestEmfPlusGetDC() +{ + // tdf#147818 EMF+ records: GetDC, DrawPath, FillRects + Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestEmfPlusGetDC.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + CPPUNIT_ASSERT(pDocument); + + assertXPath(pDocument, aXPathPrefix + "textsimpleportion", "text", "sd CCCCCCCCCCCCCCC"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion", "fontcolor", "#000000"); + + assertXPath(pDocument, aXPathPrefix + "group", 5); + assertXPath( + pDocument, aXPathPrefix + "group[4]/textsimpleportion", "text", + "Getttttttttttttttttttttttttttttt, uuuu: \"eeeeeeeeeeeeeeeeeeeeeee-7acd04a3953b\")"); + assertXPath(pDocument, aXPathPrefix + "group[5]/textsimpleportion", "text", + "TTTTTTTTTTTTTTTTTTTTTTTTTTTTT, trackId: 55)"); + assertXPath(pDocument, aXPathPrefix + "group[5]/textsimpleportion", "fontcolor", "#000000"); + + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor", 6); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]/polypolygon", "path", + "m105.78125 " + "776.111111111111h3878.64583333333l458.385416666667-493.888888888889v-176." + "388888888889h-4337.03125v670.277777777778"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]", "color", "#ffffff"); + + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[3]/polypolygon", "path", + "m2291.92708333333 4550.83333333333h317.34375v-317.5h-317.34375z"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[3]", "color", "#fcf2e3"); + + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[6]/polypolygon", "path", + "m19428.4895833333 6632.22222222222h317.34375v-2398.88888888889h-317.34375z"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[6]", "color", "#fcf2e3"); + + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke", 15); +} + +void Test::TestEmfPlusSave() +{ + // tdf#147818 EMF+ records: Save, Restore, SetWorldTransform, FillRects, SetClipRegion + Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestEmfPlusSave.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + CPPUNIT_ASSERT(pDocument); + + assertXPath(pDocument, aXPathPrefix + "mask/polypolygon", "path", "m0 0h33544v21311h-33544z"); + + assertXPath(pDocument, aXPathPrefix + "mask/group/mask/polypolygoncolor/polypolygon", "path", + "m327.458333333333 638.222222222222h437007.1875v295555.555555556h-437007.1875z"); + assertXPath(pDocument, aXPathPrefix + "mask/group/mask/polypolygoncolor", "color", "#ff0cad"); + + assertXPath(pDocument, aXPathPrefix + "mask/polypolygoncolor/polypolygon", "path", + "m10853.4145539602 7321.41354709201h41952690v29630720h-41952690z"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygoncolor", "color", "#00ffad"); + + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke/line", "color", "#000000"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke/polypolygon", "path", + "m10853.4145539602 7321.41354709201v-2413.87029012044h1979.24116969109"); +} + void Test::TestExtTextOutOpaqueAndClipTransform() { // tdf#142495 EMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUTW, MODIFYWORLDTRANSFORM, CREATEFONTINDIRECT. diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusGetDC.emf b/emfio/qa/cppunit/emf/data/TestEmfPlusGetDC.emf Binary files differnew file mode 100644 index 000000000000..665364abeefb --- /dev/null +++ b/emfio/qa/cppunit/emf/data/TestEmfPlusGetDC.emf diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusSave.emf b/emfio/qa/cppunit/emf/data/TestEmfPlusSave.emf Binary files differnew file mode 100644 index 000000000000..24662233b8cd --- /dev/null +++ b/emfio/qa/cppunit/emf/data/TestEmfPlusSave.emf |