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 |