From 6cec94d9be44f6bd1c1110dd45e9d5f9272ba479 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Sun, 8 Mar 2020 21:46:06 +0000 Subject: [PATCH] Bug 1620328 - Set conic-gradient angle range on Skia. r=lsalzman Differential Revision: https://phabricator.services.mozilla.com/D65910 --HG-- extra : moz-landing-system : lando --- gfx/2d/2D.h | 14 +++++++++++--- gfx/2d/DrawTargetSkia.cpp | 5 ++++- gfx/2d/DrawTargetWrapAndRecord.cpp | 5 +++-- gfx/2d/PatternHelpers.h | 8 ++++---- gfx/2d/RecordedEvent.h | 2 ++ gfx/2d/RecordedEventImpl.h | 8 ++++++-- gfx/thebes/gfxPattern.cpp | 6 ++++-- gfx/thebes/gfxPattern.h | 3 ++- layout/painting/nsCSSRenderingGradients.cpp | 5 +++-- 9 files changed, 39 insertions(+), 17 deletions(-) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index aceae8eb323c..86518f9e88d9 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -298,14 +298,22 @@ class RadialGradientPattern : public Pattern { class ConicGradientPattern : public Pattern { public: /// For constructor parameter description, see member data documentation. - ConicGradientPattern(const Point& aCenter, Float aAngle, - GradientStops* aStops, const Matrix& aMatrix = Matrix()) - : mCenter(aCenter), mAngle(aAngle), mStops(aStops), mMatrix(aMatrix) {} + ConicGradientPattern(const Point& aCenter, Float aAngle, Float aStartOffset, + Float aEndOffset, GradientStops* aStops, + const Matrix& aMatrix = Matrix()) + : mCenter(aCenter), + mAngle(aAngle), + mStartOffset(aStartOffset), + mEndOffset(aEndOffset), + mStops(aStops), + mMatrix(aMatrix) {} PatternType GetType() const override { return PatternType::CONIC_GRADIENT; } Point mCenter; //!< Center of the gradient Float mAngle; //!< Start angle of gradient + Float mStartOffset; // Offset of first stop + Float mEndOffset; // Offset of last stop RefPtr mStops; /**< GradientStops object for this gradient, this should match the backend type of the draw target diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index a4b15cc4b33f..910a8ab220d4 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -527,9 +527,12 @@ static void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, mat.preRotate(angle, cx, cy); } + SkTileMode mode = ExtendModeToTileMode(stops->mExtendMode, Axis::BOTH); sk_sp shader = SkGradientShader::MakeSweep( cx, cy, &stops->mColors.front(), &stops->mPositions.front(), - stops->mCount, 0, &mat); + stops->mCount, mode, 360 * pat.mStartOffset, 360 * pat.mEndOffset, + 0, &mat); + if (shader) { aPaint.setShader(shader); } else { diff --git a/gfx/2d/DrawTargetWrapAndRecord.cpp b/gfx/2d/DrawTargetWrapAndRecord.cpp index 81027ea88f1c..c89eacd816a1 100644 --- a/gfx/2d/DrawTargetWrapAndRecord.cpp +++ b/gfx/2d/DrawTargetWrapAndRecord.cpp @@ -262,8 +262,9 @@ struct AdjustedPattern final { ConicGradientPattern* conGradPat = static_cast(mOrigPattern); mPattern = new (mConGradPat) ConicGradientPattern( - conGradPat->mCenter, conGradPat->mAngle, - GetGradientStops(conGradPat->mStops), conGradPat->mMatrix); + conGradPat->mCenter, conGradPat->mAngle, conGradPat->mStartOffset, + conGradPat->mEndOffset, GetGradientStops(conGradPat->mStops), + conGradPat->mMatrix); return mPattern; } default: diff --git a/gfx/2d/PatternHelpers.h b/gfx/2d/PatternHelpers.h index e289bc3125b2..67267b8cb008 100644 --- a/gfx/2d/PatternHelpers.h +++ b/gfx/2d/PatternHelpers.h @@ -91,11 +91,11 @@ class GeneralPattern final { } ConicGradientPattern* InitConicGradientPattern( - const Point& aCenter, Float aAngle, GradientStops* aStops, - const Matrix& aMatrix = Matrix()) { + const Point& aCenter, Float aAngle, Float aStartOffset, Float aEndOffset, + GradientStops* aStops, const Matrix& aMatrix = Matrix()) { MOZ_ASSERT(!mPattern); - mPattern = new (mConicGradientPattern.addr()) - ConicGradientPattern(aCenter, aAngle, aStops, aMatrix); + mPattern = new (mConicGradientPattern.addr()) ConicGradientPattern( + aCenter, aAngle, aStartOffset, aEndOffset, aStops, aMatrix); return mConicGradientPattern.addr(); } diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index 35ad2f8dc2c7..685b74d72fcb 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -133,6 +133,8 @@ struct RadialGradientPatternStorage { struct ConicGradientPatternStorage { Point mCenter; Float mAngle; + Float mStartOffset; + Float mEndOffset; ReferencePtr mStops; Matrix mMatrix; }; diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 8cdc05509691..049fe7054cff 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -1680,6 +1680,8 @@ inline void RecordedEvent::StorePattern(PatternStorage& aDestination, static_cast(&aSource); store->mCenter = pat->mCenter; store->mAngle = pat->mAngle; + store->mStartOffset = pat->mStartOffset; + store->mEndOffset = pat->mEndOffset; store->mMatrix = pat->mMatrix; store->mStops = pat->mStops.get(); return; @@ -1832,7 +1834,8 @@ inline void RecordedEvent::OutputSimplePatternInfo( reinterpret_cast( &aStorage.mStorage); aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", " - << store->mCenter.y << ") Angle: " << store->mAngle; + << store->mCenter.y << ") Angle: " << store->mAngle + << " Range:" << store->mStartOffset << " - " << store->mEndOffset; return; } case PatternType::SURFACE: { @@ -2183,7 +2186,8 @@ struct GenericPattern { ConicGradientPatternStorage* storage = reinterpret_cast(&mStorage->mStorage); mPattern = new (mConGradPat) ConicGradientPattern( - storage->mCenter, storage->mAngle, + storage->mCenter, storage->mAngle, storage->mStartOffset, + storage->mEndOffset, storage->mStops ? mTranslator->LookupGradientStops(storage->mStops) : nullptr, storage->mMatrix); diff --git a/gfx/thebes/gfxPattern.cpp b/gfx/thebes/gfxPattern.cpp index 86b6eacd6753..6ad46cc9f6e6 100644 --- a/gfx/thebes/gfxPattern.cpp +++ b/gfx/thebes/gfxPattern.cpp @@ -38,9 +38,11 @@ gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0, } // conic -gfxPattern::gfxPattern(gfxFloat cx, gfxFloat cy, gfxFloat angle) +gfxPattern::gfxPattern(gfxFloat cx, gfxFloat cy, gfxFloat angle, + gfxFloat startOffset, gfxFloat endOffset) : mExtend(ExtendMode::CLAMP) { - mGfxPattern.InitConicGradientPattern(Point(cx, cy), angle, nullptr); + mGfxPattern.InitConicGradientPattern(Point(cx, cy), angle, startOffset, + endOffset, nullptr); } // Azure diff --git a/gfx/thebes/gfxPattern.h b/gfx/thebes/gfxPattern.h index 82978e04c9be..5eb0942e83d6 100644 --- a/gfx/thebes/gfxPattern.h +++ b/gfx/thebes/gfxPattern.h @@ -26,7 +26,8 @@ class gfxPattern final { gfxPattern(gfxFloat x0, gfxFloat y0, gfxFloat x1, gfxFloat y1); // linear gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0, gfxFloat cx1, gfxFloat cy1, gfxFloat radius1); // radial - gfxPattern(gfxFloat cx, gfxFloat cy, gfxFloat angle); // conic + gfxPattern(gfxFloat cx, gfxFloat cy, gfxFloat angle, gfxFloat startOffset, + gfxFloat endOffset); // conic gfxPattern(mozilla::gfx::SourceSurface* aSurface, const mozilla::gfx::Matrix& aPatternToUserSpace); diff --git a/layout/painting/nsCSSRenderingGradients.cpp b/layout/painting/nsCSSRenderingGradients.cpp index 288ac2ec6e59..ace0ae21e5aa 100644 --- a/layout/painting/nsCSSRenderingGradients.cpp +++ b/layout/painting/nsCSSRenderingGradients.cpp @@ -897,7 +897,7 @@ void nsCSSGradientRenderer::Paint(gfxContext& aContext, const nsRect& aDest, // This keeps the gradient line as large as the box and doesn't // lets us avoiding having to get padding correct for stops // at 0 and 1 - if (!mGradient->Repeating() || stopDelta == 0.0) { + if (!mGradient->Repeating() || (!mGradient->IsConic() && stopDelta == 0.0)) { stopOrigin = std::min(stopOrigin, 0.0); stopEnd = std::max(stopEnd, 1.0); } @@ -951,7 +951,8 @@ void nsCSSGradientRenderer::Paint(gfxContext& aContext, const nsRect& aDest, matrix.PreTranslate(-mLineStart); } } else { - gradientPattern = new gfxPattern(mCenter.x, mCenter.y, mAngle); + gradientPattern = + new gfxPattern(mCenter.x, mCenter.y, mAngle, stopOrigin, stopEnd); } // Use a pattern transform to take account of source and dest rects matrix.PreTranslate(gfxPoint(mPresContext->CSSPixelsToDevPixels(aSrc.x),