Bug 1900530 - Allow gradient defined by a single color stop. r=layout-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D233218
This commit is contained in:
Jonathan Kew
2025-01-06 19:50:26 +00:00
parent 46933ebefe
commit 24f94d5353
4 changed files with 13 additions and 11 deletions

View File

@@ -127,7 +127,7 @@ impl GradientBuilder {
/// the amount to adjust the gradient line start and stop. /// the amount to adjust the gradient line start and stop.
fn normalize(&mut self, extend_mode: di::ExtendMode) -> (f32, f32) { fn normalize(&mut self, extend_mode: di::ExtendMode) -> (f32, f32) {
let stops = &mut self.stops; let stops = &mut self.stops;
assert!(stops.len() >= 2); assert!(stops.len() >= 1);
let first = *stops.first().unwrap(); let first = *stops.first().unwrap();
let last = *stops.last().unwrap(); let last = *stops.last().unwrap();

View File

@@ -608,8 +608,8 @@ static nsTArray<ColorStop> ComputeColorStopsForItems(
ComputedStyle* aComputedStyle, ComputedStyle* aComputedStyle,
Span<const StyleGenericGradientItem<StyleColor, T>> aItems, Span<const StyleGenericGradientItem<StyleColor, T>> aItems,
CSSCoord aLineLength) { CSSCoord aLineLength) {
MOZ_ASSERT(aItems.Length() >= 2, MOZ_ASSERT(!aItems.IsEmpty(),
"The parser should reject gradients with less than two stops"); "The parser should reject gradients with no stops");
nsTArray<ColorStop> stops(aItems.Length()); nsTArray<ColorStop> stops(aItems.Length());

View File

@@ -52,12 +52,14 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
void CreateStops() { void CreateStops() {
// This loop intentionally iterates extra stops at the beginning and end // This loop intentionally iterates extra stops at the beginning and end
// if extending was requested. // if extending was requested, or in the degenerate case where only one
uint32_t iterStops = mStops.Length() - 1 + (mExtend ? 2 : 0); // color stop was specified.
const bool extend = mExtend || mStops.Length() == 1;
const uint32_t iterStops = mStops.Length() - 1 + (extend ? 2 : 0);
for (uint32_t i = 0; i < iterStops; i++) { for (uint32_t i = 0; i < iterStops; i++) {
auto thisindex = mExtend ? (i == 0 ? 0 : i - 1) : i; auto thisindex = extend ? (i == 0 ? 0 : i - 1) : i;
auto nextindex = auto nextindex =
mExtend && (i == iterStops - 1 || i == 0) ? thisindex : thisindex + 1; extend && (i == iterStops - 1 || i == 0) ? thisindex : thisindex + 1;
const auto& start = mStops[thisindex]; const auto& start = mStops[thisindex];
const auto& end = mStops[nextindex]; const auto& end = mStops[nextindex];
float startPosition = start.mPosition; float startPosition = start.mPosition;
@@ -68,7 +70,7 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
// //
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1885716 for more info. // See https://bugzilla.mozilla.org/show_bug.cgi?id=1885716 for more info.
uint32_t extraStops = 0; uint32_t extraStops = 0;
if (mExtend) { if (extend) {
// If we're extending, we just need a single new stop, which will // If we're extending, we just need a single new stop, which will
// duplicate the end being extended; do not create interpolated stops // duplicate the end being extended; do not create interpolated stops
// within in the extension area! // within in the extension area!

View File

@@ -786,7 +786,7 @@ impl Gradient {
) -> Result<LengthPercentageItemList, ParseError<'i>> { ) -> Result<LengthPercentageItemList, ParseError<'i>> {
let items = let items =
generic::GradientItem::parse_comma_separated(context, input, LengthPercentage::parse)?; generic::GradientItem::parse_comma_separated(context, input, LengthPercentage::parse)?;
if items.len() < 2 { if items.is_empty() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }
Ok(items) Ok(items)
@@ -966,7 +966,7 @@ impl Gradient {
AngleOrPercentage::parse_with_unitless, AngleOrPercentage::parse_with_unitless,
)?; )?;
if items.len() < 2 { if items.is_empty() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }
@@ -1249,7 +1249,7 @@ impl<T> generic::GradientItem<Color, T> {
} }
} }
if !seen_stop || items.len() < 2 { if !seen_stop || items.is_empty() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }
Ok(items.into()) Ok(items.into())