vcl/qa/cppunit/outdev.cxx | 59 +++++++++++++++++++++++++++++++++++++++++ vcl/source/outdev/gradient.cxx | 58 ++++++++++++++++++++++------------------ 2 files changed, 92 insertions(+), 25 deletions(-)
New commits: commit 82275140a56750302265a5be21236ae7a15f16e6 Author: Chris Sherlock <chris.sherloc...@gmail.com> AuthorDate: Sat Oct 2 23:04:02 2021 +1000 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Fri Oct 22 14:39:36 2021 +0200 vcl: move variable declar's closer to 1st use in DrawComplexGradientToMetaFile Change-Id: Id626799d1b077e649f67a8abf335a63efd15d433 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123000 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 3779d9b96536..5e05a5acd48b 100644 --- a/vcl/qa/cppunit/outdev.cxx +++ b/vcl/qa/cppunit/outdev.cxx @@ -95,6 +95,7 @@ public: void testDrawGradient_rect_axial(); void testDrawGradient_polygon_linear(); void testDrawGradient_polygon_axial(); + void testDrawGradient_rect_complex(); CPPUNIT_TEST_SUITE(VclOutdevTest); CPPUNIT_TEST(testVirtualDevice); @@ -153,6 +154,7 @@ public: CPPUNIT_TEST(testDrawGradient_rect_axial); CPPUNIT_TEST(testDrawGradient_polygon_linear); CPPUNIT_TEST(testDrawGradient_polygon_axial); + CPPUNIT_TEST(testDrawGradient_rect_complex); CPPUNIT_TEST_SUITE_END(); }; @@ -2277,6 +2279,7 @@ void VclOutdevTest::testDrawGradient_polygon_linear() Gradient aGradient(GradientStyle::Linear, COL_RED, COL_WHITE); aGradient.SetBorder(100); + pVDev->DrawGradient(aPolyPolygon, aGradient); size_t nIndex = ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); @@ -2296,6 +2299,7 @@ void VclOutdevTest::testDrawGradient_polygon_axial() Gradient aGradient(GradientStyle::Axial, COL_RED, COL_WHITE); aGradient.SetBorder(100); + pVDev->DrawGradient(aPolyPolygon, aGradient); size_t nIndex = ClipGradientTest(aMtf, INITIAL_SETUP_ACTION_COUNT); @@ -2303,6 +2307,61 @@ void VclOutdevTest::testDrawGradient_polygon_axial() TestAxialStripes(aMtf, 3, nIndex); } +static size_t TestComplexStripes(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, + pAction->GetType()); + + for (size_t i = 1; i < nTimes; i++) + { + nIndex++; + pAction = rMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polypolygon action", MetaActionType::POLYPOLYGON, + pAction->GetType()); + + nIndex++; + pAction = rMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action", MetaActionType::FILLCOLOR, + pAction->GetType()); + } + + nIndex++; + pAction = rMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a fill color action", MetaActionType::FILLCOLOR, + pAction->GetType()); + + nIndex++; + pAction = rMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a polypolygon action", MetaActionType::POLYGON, + pAction->GetType()); + + return nIndex; +} + +void VclOutdevTest::testDrawGradient_rect_complex() +{ + ScopedVclPtrInstance<VirtualDevice> pVDev; + GDIMetaFile aMtf; + aMtf.Record(pVDev.get()); + + 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->DrawGradient(aRect, aGradient); + + size_t nIndex = INITIAL_SETUP_ACTION_COUNT; + + MetaAction* pAction = aMtf.GetAction(nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Not a gradient action (rectangle area)", MetaActionType::GRADIENT, + pAction->GetType()); + + nIndex = TestComplexStripes(aMtf, 40, nIndex); +} + CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/outdev/gradient.cxx b/vcl/source/outdev/gradient.cxx index ea4a60669a64..6bb6e8de64fc 100644 --- a/vcl/source/outdev/gradient.cxx +++ b/vcl/source/outdev/gradient.cxx @@ -808,40 +808,48 @@ void OutputDevice::DrawComplexGradientToMetafile( const tools::Rectangle& rRect, // Also for printers always use PolyPolygon, as not all printers // can print polygons on top of each other. - std::optional<tools::PolyPolygon> xPolyPoly; - tools::Rectangle aRect; - Point aCenter; - Color aStartCol( rGradient.GetStartColor() ); - Color aEndCol( rGradient.GetEndColor() ); - tools::Long nStartRed = ( static_cast<tools::Long>(aStartCol.GetRed()) * rGradient.GetStartIntensity() ) / 100; - tools::Long nStartGreen = ( static_cast<tools::Long>(aStartCol.GetGreen()) * rGradient.GetStartIntensity() ) / 100; - tools::Long nStartBlue = ( static_cast<tools::Long>(aStartCol.GetBlue()) * rGradient.GetStartIntensity() ) / 100; - tools::Long nEndRed = ( static_cast<tools::Long>(aEndCol.GetRed()) * rGradient.GetEndIntensity() ) / 100; - tools::Long nEndGreen = ( static_cast<tools::Long>(aEndCol.GetGreen()) * rGradient.GetEndIntensity() ) / 100; - tools::Long nEndBlue = ( static_cast<tools::Long>(aEndCol.GetBlue()) * rGradient.GetEndIntensity() ) / 100; - tools::Long nRedSteps = nEndRed - nStartRed; - tools::Long nGreenSteps = nEndGreen - nStartGreen; - tools::Long nBlueSteps = nEndBlue - nStartBlue; - Degree10 nAngle = rGradient.GetAngle() % 3600_deg10; - - rGradient.GetBoundRect( rRect, aRect, aCenter ); + tools::Rectangle aRect; + Point aCenter; + rGradient.GetBoundRect(rRect, aRect, aCenter); + std::optional<tools::PolyPolygon> xPolyPoly; xPolyPoly = tools::PolyPolygon( 2 ); // last parameter - true if complex gradient, false if linear - tools::Long nStepCount = GetGradientSteps( rGradient, rRect, true, true ); + tools::Long nStepCount = GetGradientSteps(rGradient, rRect, true, true); // at least three steps and at most the number of colour differences - tools::Long nSteps = std::max( nStepCount, tools::Long(2) ); - tools::Long nCalcSteps = std::abs( nRedSteps ); - tools::Long nTempSteps = std::abs( nGreenSteps ); - if ( nTempSteps > nCalcSteps ) + tools::Long nSteps = std::max(nStepCount, tools::Long(2)); + + Color aStartCol(rGradient.GetStartColor()); + Color aEndCol(rGradient.GetEndColor()); + + tools::Long nStartRed = (static_cast<tools::Long>(aStartCol.GetRed()) * rGradient.GetStartIntensity()) / 100; + tools::Long nStartGreen = (static_cast<tools::Long>(aStartCol.GetGreen()) * rGradient.GetStartIntensity()) / 100; + tools::Long nStartBlue = (static_cast<tools::Long>(aStartCol.GetBlue()) * rGradient.GetStartIntensity()) / 100; + + tools::Long nEndRed = (static_cast<tools::Long>(aEndCol.GetRed()) * rGradient.GetEndIntensity()) / 100; + tools::Long nEndGreen = (static_cast<tools::Long>(aEndCol.GetGreen()) * rGradient.GetEndIntensity()) / 100; + tools::Long nEndBlue = (static_cast<tools::Long>(aEndCol.GetBlue()) * rGradient.GetEndIntensity()) / 100; + + tools::Long nRedSteps = nEndRed - nStartRed; + tools::Long nGreenSteps = nEndGreen - nStartGreen; + tools::Long nBlueSteps = nEndBlue - nStartBlue; + + tools::Long nCalcSteps = std::abs(nRedSteps); + tools::Long nTempSteps = std::abs(nGreenSteps); + + if (nTempSteps > nCalcSteps) nCalcSteps = nTempSteps; + nTempSteps = std::abs( nBlueSteps ); - if ( nTempSteps > nCalcSteps ) + + if (nTempSteps > nCalcSteps) nCalcSteps = nTempSteps; - if ( nCalcSteps < nSteps ) + + if (nCalcSteps < nSteps) nSteps = nCalcSteps; + if ( !nSteps ) nSteps = 1; @@ -892,7 +900,7 @@ void OutputDevice::DrawComplexGradientToMetafile( const tools::Rectangle& rRect, else aPoly = tools::Polygon( aRect ); - aPoly.Rotate( aCenter, nAngle ); + aPoly.Rotate(aCenter, rGradient.GetAngle() % 3600_deg10); // adapt colour accordingly const tools::Long nStepIndex = ( xPolyPoly ? i : ( i + 1 ) );