| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2015 Google Inc. All rights reserved. | 3 * Copyright (C) 2015 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 117 } |
| 118 | 118 |
| 119 struct GradientStop { | 119 struct GradientStop { |
| 120 Color color; | 120 Color color; |
| 121 float offset; | 121 float offset; |
| 122 bool specified; | 122 bool specified; |
| 123 | 123 |
| 124 GradientStop() : offset(0), specified(false) {} | 124 GradientStop() : offset(0), specified(false) {} |
| 125 }; | 125 }; |
| 126 | 126 |
| 127 struct CSSGradientValue::GradientDesc { |
| 128 STACK_ALLOCATED(); |
| 129 |
| 130 GradientDesc(const FloatPoint& p0, |
| 131 const FloatPoint& p1, |
| 132 GradientSpreadMethod spreadMethod) |
| 133 : p0(p0), p1(p1), spreadMethod(spreadMethod) {} |
| 134 GradientDesc(const FloatPoint& p0, |
| 135 const FloatPoint& p1, |
| 136 float r0, |
| 137 float r1, |
| 138 GradientSpreadMethod spreadMethod) |
| 139 : p0(p0), p1(p1), r0(r0), r1(r1), spreadMethod(spreadMethod) {} |
| 140 |
| 141 Vector<Gradient::ColorStop> stops; |
| 142 FloatPoint p0, p1; |
| 143 float r0 = 0, r1 = 0; |
| 144 GradientSpreadMethod spreadMethod = SpreadMethodPad; |
| 145 }; |
| 146 |
| 127 static void replaceColorHintsWithColorStops( | 147 static void replaceColorHintsWithColorStops( |
| 128 Vector<GradientStop>& stops, | 148 Vector<GradientStop>& stops, |
| 129 const HeapVector<CSSGradientColorStop, 2>& cssGradientStops) { | 149 const HeapVector<CSSGradientColorStop, 2>& cssGradientStops) { |
| 130 // This algorithm will replace each color interpolation hint with 9 regular | 150 // This algorithm will replace each color interpolation hint with 9 regular |
| 131 // color stops. The color values for the new color stops will be calculated | 151 // color stops. The color values for the new color stops will be calculated |
| 132 // using the color weighting formula defined in the spec. The new color | 152 // using the color weighting formula defined in the spec. The new color |
| 133 // stops will be positioned in such a way that all the pixels between the two | 153 // stops will be positioned in such a way that all the pixels between the two |
| 134 // user defined color stops have color values close to the interpolation | 154 // user defined color stops have color values close to the interpolation |
| 135 // curve. | 155 // curve. |
| 136 // If the hint is closer to the left color stop, add 2 stops to the left and | 156 // If the hint is closer to the left color stop, add 2 stops to the left and |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 indexOffset += 8; | 236 indexOffset += 8; |
| 217 } | 237 } |
| 218 } | 238 } |
| 219 | 239 |
| 220 static Color resolveStopColor(const CSSValue& stopColor, | 240 static Color resolveStopColor(const CSSValue& stopColor, |
| 221 const LayoutObject& object) { | 241 const LayoutObject& object) { |
| 222 return object.document().textLinkColors().colorFromCSSValue( | 242 return object.document().textLinkColors().colorFromCSSValue( |
| 223 stopColor, object.resolveColor(CSSPropertyColor)); | 243 stopColor, object.resolveColor(CSSPropertyColor)); |
| 224 } | 244 } |
| 225 | 245 |
| 226 void CSSGradientValue::addDeprecatedStops(Gradient* gradient, | 246 void CSSGradientValue::addDeprecatedStops(GradientDesc& desc, |
| 227 const LayoutObject& object) { | 247 const LayoutObject& object) { |
| 228 ASSERT(m_gradientType == CSSDeprecatedLinearGradient || | 248 ASSERT(m_gradientType == CSSDeprecatedLinearGradient || |
| 229 m_gradientType == CSSDeprecatedRadialGradient); | 249 m_gradientType == CSSDeprecatedRadialGradient); |
| 230 | 250 |
| 231 if (!m_stopsSorted) { | 251 if (!m_stopsSorted) { |
| 232 if (m_stops.size()) | 252 if (m_stops.size()) |
| 233 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); | 253 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); |
| 234 m_stopsSorted = true; | 254 m_stopsSorted = true; |
| 235 } | 255 } |
| 236 | 256 |
| 237 for (const auto& stop : m_stops) { | 257 for (const auto& stop : m_stops) { |
| 238 float offset; | 258 float offset; |
| 239 if (stop.m_position->isPercentage()) | 259 if (stop.m_position->isPercentage()) |
| 240 offset = stop.m_position->getFloatValue() / 100; | 260 offset = stop.m_position->getFloatValue() / 100; |
| 241 else | 261 else |
| 242 offset = stop.m_position->getFloatValue(); | 262 offset = stop.m_position->getFloatValue(); |
| 243 | 263 |
| 244 gradient->addColorStop(offset, resolveStopColor(*stop.m_color, object)); | 264 desc.stops.emplace_back(offset, resolveStopColor(*stop.m_color, object)); |
| 245 } | 265 } |
| 246 } | 266 } |
| 247 | 267 |
| 248 static bool requiresStopsNormalization(const Vector<GradientStop>& stops, | 268 static bool requiresStopsNormalization(const Vector<GradientStop>& stops, |
| 249 const Gradient* gradient) { | 269 CSSGradientValue::GradientDesc& desc) { |
| 250 // We need at least two stops to normalize | 270 // We need at least two stops to normalize |
| 251 if (stops.size() < 2) | 271 if (stops.size() < 2) |
| 252 return false; | 272 return false; |
| 253 | 273 |
| 254 // Repeating gradients are implemented using a normalized stop offset range | 274 // Repeating gradients are implemented using a normalized stop offset range |
| 255 // with the point/radius pairs aligned on the interval endpoints. | 275 // with the point/radius pairs aligned on the interval endpoints. |
| 256 if (gradient->spreadMethod() == SpreadMethodRepeat) | 276 if (desc.spreadMethod == SpreadMethodRepeat) |
| 257 return true; | 277 return true; |
| 258 | 278 |
| 259 // Degenerate stops | 279 // Degenerate stops |
| 260 if (stops.front().offset < 0 || stops.back().offset > 1) | 280 if (stops.front().offset < 0 || stops.back().offset > 1) |
| 261 return true; | 281 return true; |
| 262 | 282 |
| 263 return false; | 283 return false; |
| 264 } | 284 } |
| 265 | 285 |
| 266 // Redistribute the stops such that they fully cover [0 , 1] and add them to the | 286 // Redistribute the stops such that they fully cover [0 , 1] and add them to the |
| 267 // gradient. | 287 // gradient. |
| 268 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, | 288 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, |
| 269 Gradient* gradient) { | 289 CSSGradientValue::GradientDesc& desc) { |
| 270 ASSERT(stops.size() > 1); | 290 ASSERT(stops.size() > 1); |
| 271 | 291 |
| 272 const float firstOffset = stops.front().offset; | 292 const float firstOffset = stops.front().offset; |
| 273 const float lastOffset = stops.back().offset; | 293 const float lastOffset = stops.back().offset; |
| 274 const float span = lastOffset - firstOffset; | 294 const float span = lastOffset - firstOffset; |
| 275 | 295 |
| 276 if (fabs(span) < std::numeric_limits<float>::epsilon()) { | 296 if (fabs(span) < std::numeric_limits<float>::epsilon()) { |
| 277 // All stops are coincident -> use a single clamped offset value. | 297 // All stops are coincident -> use a single clamped offset value. |
| 278 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); | 298 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); |
| 279 | 299 |
| 280 // For repeating gradients, a coincident stop set defines a solid-color | 300 // For repeating gradients, a coincident stop set defines a solid-color |
| 281 // image with the color of the last color-stop in the rule. | 301 // image with the color of the last color-stop in the rule. |
| 282 // For non-repeating gradients, both the first color and the last color can | 302 // For non-repeating gradients, both the first color and the last color can |
| 283 // be significant (padding on both sides of the offset). | 303 // be significant (padding on both sides of the offset). |
| 284 if (gradient->spreadMethod() != SpreadMethodRepeat) | 304 if (desc.spreadMethod != SpreadMethodRepeat) |
| 285 gradient->addColorStop(clampedOffset, stops.front().color); | 305 desc.stops.emplace_back(clampedOffset, stops.front().color); |
| 286 gradient->addColorStop(clampedOffset, stops.back().color); | 306 desc.stops.emplace_back(clampedOffset, stops.back().color); |
| 287 | 307 |
| 288 return false; | 308 return false; |
| 289 } | 309 } |
| 290 | 310 |
| 291 ASSERT(span > 0); | 311 ASSERT(span > 0); |
| 292 | 312 |
| 293 for (size_t i = 0; i < stops.size(); ++i) { | 313 for (size_t i = 0; i < stops.size(); ++i) { |
| 294 const float normalizedOffset = (stops[i].offset - firstOffset) / span; | 314 const float normalizedOffset = (stops[i].offset - firstOffset) / span; |
| 295 | 315 |
| 296 // stop offsets should be monotonically increasing in [0 , 1] | 316 // stop offsets should be monotonically increasing in [0 , 1] |
| 297 ASSERT(normalizedOffset >= 0 && normalizedOffset <= 1); | 317 ASSERT(normalizedOffset >= 0 && normalizedOffset <= 1); |
| 298 ASSERT(i == 0 || | 318 ASSERT(i == 0 || |
| 299 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); | 319 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); |
| 300 | 320 |
| 301 gradient->addColorStop(normalizedOffset, stops[i].color); | 321 desc.stops.emplace_back(normalizedOffset, stops[i].color); |
| 302 } | 322 } |
| 303 | 323 |
| 304 return true; | 324 return true; |
| 305 } | 325 } |
| 306 | 326 |
| 307 // Collapse all negative-offset stops to 0 and compute an interpolated color | 327 // Collapse all negative-offset stops to 0 and compute an interpolated color |
| 308 // value for that point. | 328 // value for that point. |
| 309 static void clampNegativeOffsets(Vector<GradientStop>& stops) { | 329 static void clampNegativeOffsets(Vector<GradientStop>& stops) { |
| 310 float lastNegativeOffset = 0; | 330 float lastNegativeOffset = 0; |
| 311 | 331 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 325 break; | 345 break; |
| 326 } | 346 } |
| 327 | 347 |
| 328 // Clamp all negative stops to 0. | 348 // Clamp all negative stops to 0. |
| 329 stops[i].offset = 0; | 349 stops[i].offset = 0; |
| 330 lastNegativeOffset = currentOffset; | 350 lastNegativeOffset = currentOffset; |
| 331 } | 351 } |
| 332 } | 352 } |
| 333 | 353 |
| 334 // Update the linear gradient points to align with the given offset range. | 354 // Update the linear gradient points to align with the given offset range. |
| 335 static void adjustGradientPointsForOffsetRange(Gradient* gradient, | 355 static void adjustGradientPointsForOffsetRange( |
| 336 float firstOffset, | 356 CSSGradientValue::GradientDesc& desc, |
| 337 float lastOffset) { | 357 float firstOffset, |
| 338 ASSERT(!gradient->isRadial()); | 358 float lastOffset) { |
| 339 ASSERT(firstOffset <= lastOffset); | 359 ASSERT(firstOffset <= lastOffset); |
| 340 | 360 |
| 341 const FloatPoint p0 = gradient->p0(); | 361 const FloatPoint p0 = desc.p0; |
| 342 const FloatPoint p1 = gradient->p1(); | 362 const FloatPoint p1 = desc.p1; |
| 343 const FloatSize d(p1 - p0); | 363 const FloatSize d(p1 - p0); |
| 344 | 364 |
| 345 // Linear offsets are relative to the [p0 , p1] segment. | 365 // Linear offsets are relative to the [p0 , p1] segment. |
| 346 gradient->setP0(p0 + d * firstOffset); | 366 desc.p0 = p0 + d * firstOffset; |
| 347 gradient->setP1(p0 + d * lastOffset); | 367 desc.p1 = p0 + d * lastOffset; |
| 348 } | 368 } |
| 349 | 369 |
| 350 // Update the radial gradient radii to align with the given offset range. | 370 // Update the radial gradient radii to align with the given offset range. |
| 351 static void adjustGradientRadiiForOffsetRange(Gradient* gradient, | 371 static void adjustGradientRadiiForOffsetRange( |
| 352 float firstOffset, | 372 CSSGradientValue::GradientDesc& desc, |
| 353 float lastOffset) { | 373 float firstOffset, |
| 354 ASSERT(gradient->isRadial()); | 374 float lastOffset) { |
| 355 ASSERT(firstOffset <= lastOffset); | 375 ASSERT(firstOffset <= lastOffset); |
| 356 | 376 |
| 357 // Radial offsets are relative to the [0 , endRadius] segment. | 377 // Radial offsets are relative to the [0 , endRadius] segment. |
| 358 float adjustedR0 = gradient->endRadius() * firstOffset; | 378 float adjustedR0 = desc.r1 * firstOffset; |
| 359 float adjustedR1 = gradient->endRadius() * lastOffset; | 379 float adjustedR1 = desc.r1 * lastOffset; |
| 360 ASSERT(adjustedR0 <= adjustedR1); | 380 ASSERT(adjustedR0 <= adjustedR1); |
| 361 | 381 |
| 362 // Unlike linear gradients (where we can adjust the points arbitrarily), | 382 // Unlike linear gradients (where we can adjust the points arbitrarily), |
| 363 // we cannot let our radii turn negative here. | 383 // we cannot let our radii turn negative here. |
| 364 if (adjustedR0 < 0) { | 384 if (adjustedR0 < 0) { |
| 365 // For the non-repeat case, this can never happen: clampNegativeOffsets() | 385 // For the non-repeat case, this can never happen: clampNegativeOffsets() |
| 366 // ensures we don't have to deal with negative offsets at this point. | 386 // ensures we don't have to deal with negative offsets at this point. |
| 367 ASSERT(gradient->spreadMethod() == SpreadMethodRepeat); | 387 DCHECK_EQ(desc.spreadMethod, SpreadMethodRepeat); |
| 368 | 388 |
| 369 // When in repeat mode, we deal with it by repositioning both radii in the | 389 // When in repeat mode, we deal with it by repositioning both radii in the |
| 370 // positive domain - shifting them by a multiple of the radius span (which | 390 // positive domain - shifting them by a multiple of the radius span (which |
| 371 // is the period of our repeating gradient -> hence no visible side | 391 // is the period of our repeating gradient -> hence no visible side |
| 372 // effects). | 392 // effects). |
| 373 const float radiusSpan = adjustedR1 - adjustedR0; | 393 const float radiusSpan = adjustedR1 - adjustedR0; |
| 374 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); | 394 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); |
| 375 adjustedR0 += shiftToPositive; | 395 adjustedR0 += shiftToPositive; |
| 376 adjustedR1 += shiftToPositive; | 396 adjustedR1 += shiftToPositive; |
| 377 } | 397 } |
| 378 ASSERT(adjustedR0 >= 0); | 398 ASSERT(adjustedR0 >= 0); |
| 379 ASSERT(adjustedR1 >= adjustedR0); | 399 ASSERT(adjustedR1 >= adjustedR0); |
| 380 | 400 |
| 381 gradient->setStartRadius(adjustedR0); | 401 desc.r0 = adjustedR0; |
| 382 gradient->setEndRadius(adjustedR1); | 402 desc.r1 = adjustedR1; |
| 383 } | 403 } |
| 384 | 404 |
| 385 void CSSGradientValue::addStops(Gradient* gradient, | 405 void CSSGradientValue::addStops(CSSGradientValue::GradientDesc& desc, |
| 386 const CSSToLengthConversionData& conversionData, | 406 const CSSToLengthConversionData& conversionData, |
| 387 const LayoutObject& object) { | 407 const LayoutObject& object) { |
| 388 if (m_gradientType == CSSDeprecatedLinearGradient || | 408 if (m_gradientType == CSSDeprecatedLinearGradient || |
| 389 m_gradientType == CSSDeprecatedRadialGradient) { | 409 m_gradientType == CSSDeprecatedRadialGradient) { |
| 390 addDeprecatedStops(gradient, object); | 410 addDeprecatedStops(desc, object); |
| 391 return; | 411 return; |
| 392 } | 412 } |
| 393 | 413 |
| 394 size_t numStops = m_stops.size(); | 414 size_t numStops = m_stops.size(); |
| 395 | 415 |
| 396 Vector<GradientStop> stops(numStops); | 416 Vector<GradientStop> stops(numStops); |
| 397 | 417 |
| 398 bool hasHints = false; | 418 bool hasHints = false; |
| 399 | 419 |
| 400 FloatPoint gradientStart = gradient->p0(); | 420 FloatPoint gradientStart = desc.p0; |
| 401 FloatPoint gradientEnd; | 421 FloatPoint gradientEnd; |
| 402 if (isLinearGradientValue()) | 422 if (isLinearGradientValue()) |
| 403 gradientEnd = gradient->p1(); | 423 gradientEnd = desc.p1; |
| 404 else if (isRadialGradientValue()) | 424 else if (isRadialGradientValue()) |
| 405 gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0); | 425 gradientEnd = gradientStart + FloatSize(desc.r1, 0); |
| 406 float gradientLength = | 426 float gradientLength = |
| 407 FloatSize(gradientStart - gradientEnd).diagonalLength(); | 427 FloatSize(gradientStart - gradientEnd).diagonalLength(); |
| 408 | 428 |
| 409 for (size_t i = 0; i < numStops; ++i) { | 429 for (size_t i = 0; i < numStops; ++i) { |
| 410 const CSSGradientColorStop& stop = m_stops[i]; | 430 const CSSGradientColorStop& stop = m_stops[i]; |
| 411 | 431 |
| 412 if (stop.isHint()) | 432 if (stop.isHint()) |
| 413 hasHints = true; | 433 hasHints = true; |
| 414 else | 434 else |
| 415 stops[i].color = resolveStopColor(*stop.m_color, object); | 435 stops[i].color = resolveStopColor(*stop.m_color, object); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 } | 514 } |
| 495 } | 515 } |
| 496 | 516 |
| 497 ASSERT(stops.size() == m_stops.size()); | 517 ASSERT(stops.size() == m_stops.size()); |
| 498 if (hasHints) { | 518 if (hasHints) { |
| 499 replaceColorHintsWithColorStops(stops, m_stops); | 519 replaceColorHintsWithColorStops(stops, m_stops); |
| 500 } | 520 } |
| 501 | 521 |
| 502 // At this point we have a fully resolved set of stops. Time to perform | 522 // At this point we have a fully resolved set of stops. Time to perform |
| 503 // adjustments for repeat gradients and degenerate values if needed. | 523 // adjustments for repeat gradients and degenerate values if needed. |
| 504 if (requiresStopsNormalization(stops, gradient)) { | 524 if (requiresStopsNormalization(stops, desc)) { |
| 505 // Negative offsets are only an issue for non-repeating radial gradients: | 525 // Negative offsets are only an issue for non-repeating radial gradients: |
| 506 // linear gradient points can be repositioned arbitrarily, and for repeating | 526 // linear gradient points can be repositioned arbitrarily, and for repeating |
| 507 // radial gradients we shift the radii into equivalent positive values. | 527 // radial gradients we shift the radii into equivalent positive values. |
| 508 if (isRadialGradientValue() && !m_repeating) | 528 if (isRadialGradientValue() && !m_repeating) |
| 509 clampNegativeOffsets(stops); | 529 clampNegativeOffsets(stops); |
| 510 | 530 |
| 511 if (normalizeAndAddStops(stops, gradient)) { | 531 if (normalizeAndAddStops(stops, desc)) { |
| 512 if (isLinearGradientValue()) { | 532 if (isLinearGradientValue()) { |
| 513 adjustGradientPointsForOffsetRange(gradient, stops.front().offset, | 533 adjustGradientPointsForOffsetRange(desc, stops.front().offset, |
| 514 stops.back().offset); | 534 stops.back().offset); |
| 515 } else { | 535 } else { |
| 516 adjustGradientRadiiForOffsetRange(gradient, stops.front().offset, | 536 adjustGradientRadiiForOffsetRange(desc, stops.front().offset, |
| 517 stops.back().offset); | 537 stops.back().offset); |
| 518 } | 538 } |
| 519 } else { | 539 } else { |
| 520 // Normalization failed because the stop set is coincident. | 540 // Normalization failed because the stop set is coincident. |
| 521 } | 541 } |
| 522 } else { | 542 } else { |
| 523 // No normalization required, just add the current stops. | 543 // No normalization required, just add the current stops. |
| 524 for (const auto& stop : stops) | 544 for (const auto& stop : stops) |
| 525 gradient->addColorStop(stop.offset, stop.color); | 545 desc.stops.emplace_back(stop.offset, stop.color); |
| 526 } | 546 } |
| 527 } | 547 } |
| 528 | 548 |
| 529 static float positionFromValue(const CSSValue* value, | 549 static float positionFromValue(const CSSValue* value, |
| 530 const CSSToLengthConversionData& conversionData, | 550 const CSSToLengthConversionData& conversionData, |
| 531 const IntSize& size, | 551 const IntSize& size, |
| 532 bool isHorizontal) { | 552 bool isHorizontal) { |
| 533 int origin = 0; | 553 int origin = 0; |
| 534 int sign = 1; | 554 int sign = 1; |
| 535 int edgeDistance = isHorizontal ? size.width() : size.height(); | 555 int edgeDistance = isHorizontal ? size.width() : size.height(); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 if (m_firstY) | 891 if (m_firstY) |
| 872 firstPoint.setY(size.height() - secondPoint.y()); | 892 firstPoint.setY(size.height() - secondPoint.y()); |
| 873 } else | 893 } else |
| 874 secondPoint.setY(size.height()); | 894 secondPoint.setY(size.height()); |
| 875 break; | 895 break; |
| 876 default: | 896 default: |
| 877 ASSERT_NOT_REACHED(); | 897 ASSERT_NOT_REACHED(); |
| 878 } | 898 } |
| 879 } | 899 } |
| 880 | 900 |
| 901 GradientDesc desc(firstPoint, secondPoint, |
| 902 m_repeating ? SpreadMethodRepeat : SpreadMethodPad); |
| 903 addStops(desc, conversionData, object); |
| 904 |
| 881 RefPtr<Gradient> gradient = | 905 RefPtr<Gradient> gradient = |
| 882 Gradient::create(firstPoint, secondPoint, | 906 Gradient::create(desc.p0, desc.p1, desc.spreadMethod, |
| 883 m_repeating ? SpreadMethodRepeat : SpreadMethodPad, | |
| 884 Gradient::ColorInterpolation::Premultiplied); | 907 Gradient::ColorInterpolation::Premultiplied); |
| 885 | 908 |
| 886 // Now add the stops. | 909 // Now add the stops. |
| 887 addStops(gradient.get(), conversionData, object); | 910 gradient->addColorStops(desc.stops); |
| 888 | 911 |
| 889 return gradient.release(); | 912 return gradient.release(); |
| 890 } | 913 } |
| 891 | 914 |
| 892 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const { | 915 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const { |
| 893 if (m_gradientType == CSSDeprecatedLinearGradient) | 916 if (m_gradientType == CSSDeprecatedLinearGradient) |
| 894 return other.m_gradientType == m_gradientType && | 917 return other.m_gradientType == m_gradientType && |
| 895 dataEquivalent(m_firstX, other.m_firstX) && | 918 dataEquivalent(m_firstX, other.m_firstX) && |
| 896 dataEquivalent(m_firstY, other.m_firstY) && | 919 dataEquivalent(m_firstY, other.m_firstY) && |
| 897 dataEquivalent(m_secondX, other.m_secondX) && | 920 dataEquivalent(m_secondX, other.m_secondX) && |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 [](float a, float b) { return a > b; }); | 1260 [](float a, float b) { return a > b; }); |
| 1238 break; | 1261 break; |
| 1239 } | 1262 } |
| 1240 } | 1263 } |
| 1241 | 1264 |
| 1242 DCHECK(std::isfinite(firstRadius)); | 1265 DCHECK(std::isfinite(firstRadius)); |
| 1243 DCHECK(std::isfinite(secondRadius.width())); | 1266 DCHECK(std::isfinite(secondRadius.width())); |
| 1244 DCHECK(std::isfinite(secondRadius.height())); | 1267 DCHECK(std::isfinite(secondRadius.height())); |
| 1245 | 1268 |
| 1246 bool isDegenerate = !secondRadius.width() || !secondRadius.height(); | 1269 bool isDegenerate = !secondRadius.width() || !secondRadius.height(); |
| 1247 RefPtr<Gradient> gradient = | 1270 GradientDesc desc(firstPoint, secondPoint, firstRadius, |
| 1248 Gradient::create(firstPoint, firstRadius, secondPoint, | 1271 isDegenerate ? 0 : secondRadius.width(), |
| 1249 isDegenerate ? 0 : secondRadius.width(), | 1272 m_repeating ? SpreadMethodRepeat : SpreadMethodPad); |
| 1250 isDegenerate ? 1 : secondRadius.aspectRatio(), | 1273 addStops(desc, conversionData, object); |
| 1251 m_repeating ? SpreadMethodRepeat : SpreadMethodPad, | 1274 |
| 1252 Gradient::ColorInterpolation::Premultiplied); | 1275 RefPtr<Gradient> gradient = Gradient::create( |
| 1276 desc.p0, desc.r0, desc.p1, desc.r1, |
| 1277 isDegenerate ? 1 : secondRadius.aspectRatio(), desc.spreadMethod, |
| 1278 Gradient::ColorInterpolation::Premultiplied); |
| 1253 | 1279 |
| 1254 // Now add the stops. | 1280 // Now add the stops. |
| 1255 addStops(gradient.get(), conversionData, object); | 1281 gradient->addColorStops(desc.stops); |
| 1256 | 1282 |
| 1257 return gradient.release(); | 1283 return gradient.release(); |
| 1258 } | 1284 } |
| 1259 | 1285 |
| 1260 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const { | 1286 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const { |
| 1261 if (m_gradientType == CSSDeprecatedRadialGradient) | 1287 if (m_gradientType == CSSDeprecatedRadialGradient) |
| 1262 return other.m_gradientType == m_gradientType && | 1288 return other.m_gradientType == m_gradientType && |
| 1263 dataEquivalent(m_firstX, other.m_firstX) && | 1289 dataEquivalent(m_firstX, other.m_firstX) && |
| 1264 dataEquivalent(m_firstY, other.m_firstY) && | 1290 dataEquivalent(m_firstY, other.m_firstY) && |
| 1265 dataEquivalent(m_secondX, other.m_secondX) && | 1291 dataEquivalent(m_secondX, other.m_secondX) && |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 visitor->trace(m_firstRadius); | 1339 visitor->trace(m_firstRadius); |
| 1314 visitor->trace(m_secondRadius); | 1340 visitor->trace(m_secondRadius); |
| 1315 visitor->trace(m_shape); | 1341 visitor->trace(m_shape); |
| 1316 visitor->trace(m_sizingBehavior); | 1342 visitor->trace(m_sizingBehavior); |
| 1317 visitor->trace(m_endHorizontalSize); | 1343 visitor->trace(m_endHorizontalSize); |
| 1318 visitor->trace(m_endVerticalSize); | 1344 visitor->trace(m_endVerticalSize); |
| 1319 CSSGradientValue::traceAfterDispatch(visitor); | 1345 CSSGradientValue::traceAfterDispatch(visitor); |
| 1320 } | 1346 } |
| 1321 | 1347 |
| 1322 } // namespace blink | 1348 } // namespace blink |
| OLD | NEW |