| 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 // We need at least two stops to normalize | 250 // We need at least two stops to normalize |
| 251 if (stops.size() < 2) | 251 if (stops.size() < 2) |
| 252 return false; | 252 return false; |
| 253 | 253 |
| 254 // Repeating gradients are implemented using a normalized stop offset range | 254 // Repeating gradients are implemented using a normalized stop offset range |
| 255 // with the point/radius pairs aligned on the interval endpoints. | 255 // with the point/radius pairs aligned on the interval endpoints. |
| 256 if (gradient->spreadMethod() == SpreadMethodRepeat) | 256 if (gradient->spreadMethod() == SpreadMethodRepeat) |
| 257 return true; | 257 return true; |
| 258 | 258 |
| 259 // Degenerate stops | 259 // Degenerate stops |
| 260 if (stops.first().offset < 0 || stops.back().offset > 1) | 260 if (stops.front().offset < 0 || stops.back().offset > 1) |
| 261 return true; | 261 return true; |
| 262 | 262 |
| 263 return false; | 263 return false; |
| 264 } | 264 } |
| 265 | 265 |
| 266 // Redistribute the stops such that they fully cover [0 , 1] and add them to the | 266 // Redistribute the stops such that they fully cover [0 , 1] and add them to the |
| 267 // gradient. | 267 // gradient. |
| 268 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, | 268 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, |
| 269 Gradient* gradient) { | 269 Gradient* gradient) { |
| 270 ASSERT(stops.size() > 1); | 270 ASSERT(stops.size() > 1); |
| 271 | 271 |
| 272 const float firstOffset = stops.first().offset; | 272 const float firstOffset = stops.front().offset; |
| 273 const float lastOffset = stops.back().offset; | 273 const float lastOffset = stops.back().offset; |
| 274 const float span = lastOffset - firstOffset; | 274 const float span = lastOffset - firstOffset; |
| 275 | 275 |
| 276 if (fabs(span) < std::numeric_limits<float>::epsilon()) { | 276 if (fabs(span) < std::numeric_limits<float>::epsilon()) { |
| 277 // All stops are coincident -> use a single clamped offset value. | 277 // All stops are coincident -> use a single clamped offset value. |
| 278 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); | 278 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); |
| 279 | 279 |
| 280 // For repeating gradients, a coincident stop set defines a solid-color | 280 // For repeating gradients, a coincident stop set defines a solid-color |
| 281 // image with the color of the last color-stop in the rule. | 281 // 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 | 282 // For non-repeating gradients, both the first color and the last color can |
| 283 // be significant (padding on both sides of the offset). | 283 // be significant (padding on both sides of the offset). |
| 284 if (gradient->spreadMethod() != SpreadMethodRepeat) | 284 if (gradient->spreadMethod() != SpreadMethodRepeat) |
| 285 gradient->addColorStop(clampedOffset, stops.first().color); | 285 gradient->addColorStop(clampedOffset, stops.front().color); |
| 286 gradient->addColorStop(clampedOffset, stops.back().color); | 286 gradient->addColorStop(clampedOffset, stops.back().color); |
| 287 | 287 |
| 288 return false; | 288 return false; |
| 289 } | 289 } |
| 290 | 290 |
| 291 ASSERT(span > 0); | 291 ASSERT(span > 0); |
| 292 | 292 |
| 293 for (size_t i = 0; i < stops.size(); ++i) { | 293 for (size_t i = 0; i < stops.size(); ++i) { |
| 294 const float normalizedOffset = (stops[i].offset - firstOffset) / span; | 294 const float normalizedOffset = (stops[i].offset - firstOffset) / span; |
| 295 | 295 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 --prevSpecifiedIndex) { | 454 --prevSpecifiedIndex) { |
| 455 if (stops[prevSpecifiedIndex].specified) | 455 if (stops[prevSpecifiedIndex].specified) |
| 456 break; | 456 break; |
| 457 } | 457 } |
| 458 | 458 |
| 459 if (stops[i].offset < stops[prevSpecifiedIndex].offset) | 459 if (stops[i].offset < stops[prevSpecifiedIndex].offset) |
| 460 stops[i].offset = stops[prevSpecifiedIndex].offset; | 460 stops[i].offset = stops[prevSpecifiedIndex].offset; |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 ASSERT(stops.first().specified && stops.back().specified); | 464 ASSERT(stops.front().specified && stops.back().specified); |
| 465 | 465 |
| 466 // If any color-stop still does not have a position, then, for each run of | 466 // If any color-stop still does not have a position, then, for each run of |
| 467 // adjacent color-stops without positions, set their positions so that they | 467 // adjacent color-stops without positions, set their positions so that they |
| 468 // are evenly spaced between the preceding and following color-stops with | 468 // are evenly spaced between the preceding and following color-stops with |
| 469 // positions. | 469 // positions. |
| 470 if (numStops > 2) { | 470 if (numStops > 2) { |
| 471 size_t unspecifiedRunStart = 0; | 471 size_t unspecifiedRunStart = 0; |
| 472 bool inUnspecifiedRun = false; | 472 bool inUnspecifiedRun = false; |
| 473 | 473 |
| 474 for (size_t i = 0; i < numStops; ++i) { | 474 for (size_t i = 0; i < numStops; ++i) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 503 // adjustments for repeat gradients and degenerate values if needed. | 503 // adjustments for repeat gradients and degenerate values if needed. |
| 504 if (requiresStopsNormalization(stops, gradient)) { | 504 if (requiresStopsNormalization(stops, gradient)) { |
| 505 // Negative offsets are only an issue for non-repeating radial gradients: | 505 // Negative offsets are only an issue for non-repeating radial gradients: |
| 506 // linear gradient points can be repositioned arbitrarily, and for repeating | 506 // linear gradient points can be repositioned arbitrarily, and for repeating |
| 507 // radial gradients we shift the radii into equivalent positive values. | 507 // radial gradients we shift the radii into equivalent positive values. |
| 508 if (isRadialGradientValue() && !m_repeating) | 508 if (isRadialGradientValue() && !m_repeating) |
| 509 clampNegativeOffsets(stops); | 509 clampNegativeOffsets(stops); |
| 510 | 510 |
| 511 if (normalizeAndAddStops(stops, gradient)) { | 511 if (normalizeAndAddStops(stops, gradient)) { |
| 512 if (isLinearGradientValue()) { | 512 if (isLinearGradientValue()) { |
| 513 adjustGradientPointsForOffsetRange(gradient, stops.first().offset, | 513 adjustGradientPointsForOffsetRange(gradient, stops.front().offset, |
| 514 stops.back().offset); | 514 stops.back().offset); |
| 515 } else { | 515 } else { |
| 516 adjustGradientRadiiForOffsetRange(gradient, stops.first().offset, | 516 adjustGradientRadiiForOffsetRange(gradient, stops.front().offset, |
| 517 stops.back().offset); | 517 stops.back().offset); |
| 518 } | 518 } |
| 519 } else { | 519 } else { |
| 520 // Normalization failed because the stop set is coincident. | 520 // Normalization failed because the stop set is coincident. |
| 521 } | 521 } |
| 522 } else { | 522 } else { |
| 523 // No normalization required, just add the current stops. | 523 // No normalization required, just add the current stops. |
| 524 for (const auto& stop : stops) | 524 for (const auto& stop : stops) |
| 525 gradient->addColorStop(stop.offset, stop.color); | 525 gradient->addColorStop(stop.offset, stop.color); |
| 526 } | 526 } |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 visitor->trace(m_firstRadius); | 1317 visitor->trace(m_firstRadius); |
| 1318 visitor->trace(m_secondRadius); | 1318 visitor->trace(m_secondRadius); |
| 1319 visitor->trace(m_shape); | 1319 visitor->trace(m_shape); |
| 1320 visitor->trace(m_sizingBehavior); | 1320 visitor->trace(m_sizingBehavior); |
| 1321 visitor->trace(m_endHorizontalSize); | 1321 visitor->trace(m_endHorizontalSize); |
| 1322 visitor->trace(m_endVerticalSize); | 1322 visitor->trace(m_endVerticalSize); |
| 1323 CSSGradientValue::traceAfterDispatch(visitor); | 1323 CSSGradientValue::traceAfterDispatch(visitor); |
| 1324 } | 1324 } |
| 1325 | 1325 |
| 1326 } // namespace blink | 1326 } // namespace blink |
| OLD | NEW |