vcl/qa/cppunit/outdev.cxx | 112 ++++++++++++++++++++++++++++++++++++----- vcl/source/outdev/gradient.cxx | 46 +--------------- 2 files changed, 106 insertions(+), 52 deletions(-)
New commits: commit 1de7e1f4640bad725626b574b33eb2db9244f378 Author: Chris Sherlock <chris.sherloc...@gmail.com> AuthorDate: Tue Dec 14 19:09:39 2021 +1100 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Dec 27 03:47:28 2021 +0100 vcl: remove unnecessary actions from DrawGradientToMetafile() It turns out, we never actually needed to decompose the gradient into seperate actions in DrawGradientToMetafile(). We still need this for AddGradientActions() however. Update tests and add new ones for AddGradientActions(). Change-Id: I2115da8e7d1efa5bcd2a8f4f00d9678216549e4f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126846 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx index 469a24521643..dc2ea8ad2ed2 100644 --- a/vcl/qa/cppunit/outdev.cxx +++ b/vcl/qa/cppunit/outdev.cxx @@ -10,6 +10,7 @@ #include <test/bootstrapfixture.hxx> #include <test/outputdevice.hxx> +#include <sal/log.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/polygon/b2dpolygon.hxx> @@ -93,9 +94,12 @@ public: void testDrawGradient_drawmode(); void testDrawGradient_rect_linear(); void testDrawGradient_rect_axial(); + void testAddGradientActions_rect_linear(); + void testAddGradientActions_rect_axial(); void testDrawGradient_polygon_linear(); void testDrawGradient_polygon_axial(); void testDrawGradient_rect_complex(); + void testAddGradientActions_rect_complex(); CPPUNIT_TEST_SUITE(VclOutdevTest); CPPUNIT_TEST(testVirtualDevice); @@ -152,9 +156,12 @@ public: CPPUNIT_TEST(testDrawGradient_drawmode); CPPUNIT_TEST(testDrawGradient_rect_linear); CPPUNIT_TEST(testDrawGradient_rect_axial); + CPPUNIT_TEST(testAddGradientActions_rect_linear); + CPPUNIT_TEST(testAddGradientActions_rect_axial); CPPUNIT_TEST(testDrawGradient_polygon_linear); CPPUNIT_TEST(testDrawGradient_polygon_axial); CPPUNIT_TEST(testDrawGradient_rect_complex); + CPPUNIT_TEST(testAddGradientActions_rect_complex); CPPUNIT_TEST_SUITE_END(); }; @@ -2135,12 +2142,12 @@ static size_t TestLinearStripes(GDIMetaFile& rMtf, size_t nTimes, size_t nIndex) { nIndex++; MetaAction* pAction = rMtf.GetAction(nIndex); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action", MetaActionType::FILLCOLOR, + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action (start)", MetaActionType::FILLCOLOR, pAction->GetType()); nIndex++; pAction = rMtf.GetAction(nIndex); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polygon action", MetaActionType::POLYGON, + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polygon action (start)", MetaActionType::POLYGON, pAction->GetType()); for (size_t i = 0; i < nTimes - 1; i++) @@ -2158,12 +2165,12 @@ static size_t TestLinearStripes(GDIMetaFile& rMtf, size_t nTimes, size_t nIndex) nIndex++; pAction = rMtf.GetAction(nIndex); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action", MetaActionType::FILLCOLOR, + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action (end)", MetaActionType::FILLCOLOR, pAction->GetType()); nIndex++; pAction = rMtf.GetAction(nIndex); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polygon action", MetaActionType::POLYGON, + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polygon action (end)", MetaActionType::POLYGON, pAction->GetType()); return nIndex; @@ -2236,6 +2243,35 @@ void VclOutdevTest::testDrawGradient_rect_linear() MetaAction* pAction = aMtf.GetAction(nIndex); CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a gradient action (rectangle area)", MetaActionType::GRADIENT, pAction->GetType()); +} + +void VclOutdevTest::testAddGradientActions_rect_linear() +{ + ScopedVclPtrInstance<VirtualDevice> pVDev; + GDIMetaFile aMtf; + + tools::Rectangle aRect(Point(10, 10), Size(40, 40)); + pVDev->SetOutputSizePixel(Size(100, 100)); + + Gradient aGradient(GradientStyle::Linear, COL_RED, COL_WHITE); + aGradient.SetBorder(100); + + pVDev->AddGradientActions(aRect, aGradient, aMtf); + + size_t nIndex = 0; + + MetaAction* pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a push action", MetaActionType::PUSH, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a rectangular intersect clip action", + MetaActionType::ISECTRECTCLIPREGION, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a line color action", MetaActionType::LINECOLOR, + pAction->GetType()); TestLinearStripes(aMtf, 3, nIndex); } @@ -2259,6 +2295,35 @@ void VclOutdevTest::testDrawGradient_rect_axial() MetaAction* pAction = aMtf.GetAction(nIndex); CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a gradient action (rectangle area)", MetaActionType::GRADIENT, pAction->GetType()); +} + +void VclOutdevTest::testAddGradientActions_rect_axial() +{ + ScopedVclPtrInstance<VirtualDevice> pVDev; + GDIMetaFile aMtf; + + tools::Rectangle aRect(Point(10, 10), Size(40, 40)); + pVDev->SetOutputSizePixel(Size(100, 100)); + + Gradient aGradient(GradientStyle::Axial, COL_RED, COL_WHITE); + aGradient.SetBorder(100); + + pVDev->AddGradientActions(aRect, aGradient, aMtf); + + size_t nIndex = 0; + + MetaAction* pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a push action", MetaActionType::PUSH, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a rectangular intersect clip action", + MetaActionType::ISECTRECTCLIPREGION, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a line color action", MetaActionType::LINECOLOR, + pAction->GetType()); TestAxialStripes(aMtf, 3, nIndex); } @@ -2278,9 +2343,7 @@ void VclOutdevTest::testDrawGradient_polygon_linear() pVDev->DrawGradient(aPolyPolygon, aGradient); - size_t nIndex = ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); - - TestLinearStripes(aMtf, 3, nIndex); + ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); } void VclOutdevTest::testDrawGradient_polygon_axial() @@ -2298,9 +2361,7 @@ void VclOutdevTest::testDrawGradient_polygon_axial() pVDev->DrawGradient(aPolyPolygon, aGradient); - size_t nIndex = ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); - - TestAxialStripes(aMtf, 3, nIndex); + ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); } static size_t TestComplexStripes(GDIMetaFile& rMtf, size_t nTimes, size_t nIndex) @@ -2354,8 +2415,37 @@ void VclOutdevTest::testDrawGradient_rect_complex() MetaAction* pAction = aMtf.GetAction(nIndex); CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a gradient action (rectangle area)", MetaActionType::GRADIENT, pAction->GetType()); +} + +void VclOutdevTest::testAddGradientActions_rect_complex() +{ + ScopedVclPtrInstance<VirtualDevice> pVDev; + GDIMetaFile aMtf; + + tools::Rectangle aRect(Point(10, 10), Size(40, 40)); + pVDev->SetOutputSizePixel(Size(1000, 1000)); + + Gradient aGradient(GradientStyle::Square, COL_RED, COL_WHITE); + aGradient.SetBorder(10); + + pVDev->AddGradientActions(aRect, aGradient, aMtf); + + size_t nIndex = 0; + + MetaAction* pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a push action", MetaActionType::PUSH, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a rectangular intersect clip action", + MetaActionType::ISECTRECTCLIPREGION, pAction->GetType()); + + nIndex++; + pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a line color action", MetaActionType::LINECOLOR, + pAction->GetType()); - nIndex = TestComplexStripes(aMtf, 40, nIndex); + TestComplexStripes(aMtf, 40, nIndex); } CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); diff --git a/vcl/source/outdev/gradient.cxx b/vcl/source/outdev/gradient.cxx index 7dc5523480db..f1ae13283f9d 100644 --- a/vcl/source/outdev/gradient.cxx +++ b/vcl/source/outdev/gradient.cxx @@ -183,13 +183,16 @@ void OutputDevice::DrawGradientToMetafile ( const tools::PolyPolygon& rPolyPoly, if ( !(rPolyPoly.Count() && rPolyPoly[ 0 ].GetSize()) ) return; + const tools::Rectangle aBoundRect( rPolyPoly.GetBoundRect() ); + + if (aBoundRect.IsEmpty()) + return; + Gradient aGradient( rGradient ); if (mnDrawMode & DrawModeFlags::GrayGradient) aGradient.MakeGrayscale(); - const tools::Rectangle aBoundRect( rPolyPoly.GetBoundRect() ); - if ( rPolyPoly.IsRect() ) { mpMetaFile->AddAction( new MetaGradientAction( aBoundRect, aGradient ) ); @@ -203,45 +206,6 @@ void OutputDevice::DrawGradientToMetafile ( const tools::PolyPolygon& rPolyPoly, mpMetaFile->AddAction( new MetaCommentAction( "XGRAD_SEQ_END" ) ); } - - if( !IsDeviceOutputNecessary() || ImplIsRecordLayout() ) - return; - - // Clip and then draw the gradient - if( tools::Rectangle( PixelToLogic( Point() ), GetOutputSize() ).IsEmpty() ) - return; - - // convert rectangle to pixels - tools::Rectangle aRect( ImplLogicToDevicePixel( aBoundRect ) ); - aRect.Justify(); - - // do nothing if the rectangle is empty - if ( aRect.IsEmpty() ) - return; - - if( mbOutputClipped ) - return; - - // calculate step count if necessary - if ( !aGradient.GetSteps() ) - aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT ); - - if ( rPolyPoly.IsRect() ) - { - // because we draw with no border line, we have to expand gradient - // rect to avoid missing lines on the right and bottom edge - aRect.AdjustLeft( -1 ); - aRect.AdjustTop( -1 ); - aRect.AdjustRight( 1 ); - aRect.AdjustBottom( 1 ); - } - - // if the clipping polypolygon is a rectangle, then it's the same size as the bounding of the - // polypolygon, so pass in a NULL for the clipping parameter - if( aGradient.GetStyle() == GradientStyle::Linear || rGradient.GetStyle() == GradientStyle::Axial ) - DrawLinearGradientToMetafile( aRect, aGradient ); - else - DrawComplexGradientToMetafile( aRect, aGradient ); } namespace