| 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 | 207 |
| 208 int indexOffset = 0; | 208 int indexOffset = 0; |
| 209 | 209 |
| 210 // The first and the last color stops cannot be color hints. | 210 // The first and the last color stops cannot be color hints. |
| 211 for (size_t i = 1; i < cssGradientStops.size() - 1; ++i) { | 211 for (size_t i = 1; i < cssGradientStops.size() - 1; ++i) { |
| 212 if (!cssGradientStops[i].isHint()) | 212 if (!cssGradientStops[i].isHint()) |
| 213 continue; | 213 continue; |
| 214 | 214 |
| 215 // The current index of the stops vector. | 215 // The current index of the stops vector. |
| 216 size_t x = i + indexOffset; | 216 size_t x = i + indexOffset; |
| 217 ASSERT(x >= 1); | 217 DCHECK_GE(x, 1u); |
| 218 | 218 |
| 219 // offsetLeft offset offsetRight | 219 // offsetLeft offset offsetRight |
| 220 // |-------------------|---------------------------------| | 220 // |-------------------|---------------------------------| |
| 221 // leftDist rightDist | 221 // leftDist rightDist |
| 222 | 222 |
| 223 float offsetLeft = stops[x - 1].offset; | 223 float offsetLeft = stops[x - 1].offset; |
| 224 float offsetRight = stops[x + 1].offset; | 224 float offsetRight = stops[x + 1].offset; |
| 225 float offset = stops[x].offset; | 225 float offset = stops[x].offset; |
| 226 float leftDist = offset - offsetLeft; | 226 float leftDist = offset - offsetLeft; |
| 227 float rightDist = offsetRight - offset; | 227 float rightDist = offsetRight - offset; |
| 228 float totalDist = offsetRight - offsetLeft; | 228 float totalDist = offsetRight - offsetLeft; |
| 229 | 229 |
| 230 Color leftColor = stops[x - 1].color; | 230 Color leftColor = stops[x - 1].color; |
| 231 Color rightColor = stops[x + 1].color; | 231 Color rightColor = stops[x + 1].color; |
| 232 | 232 |
| 233 ASSERT(offsetLeft <= offset && offset <= offsetRight); | 233 DCHECK_LE(offsetLeft, offset); |
| 234 DCHECK_LE(offset, offsetRight); |
| 234 | 235 |
| 235 if (WebCoreFloatNearlyEqual(leftDist, rightDist)) { | 236 if (WebCoreFloatNearlyEqual(leftDist, rightDist)) { |
| 236 stops.erase(x); | 237 stops.erase(x); |
| 237 --indexOffset; | 238 --indexOffset; |
| 238 continue; | 239 continue; |
| 239 } | 240 } |
| 240 | 241 |
| 241 if (WebCoreFloatNearlyEqual(leftDist, .0f)) { | 242 if (WebCoreFloatNearlyEqual(leftDist, .0f)) { |
| 242 stops[x].color = rightColor; | 243 stops[x].color = rightColor; |
| 243 continue; | 244 continue; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 } | 282 } |
| 282 | 283 |
| 283 static Color resolveStopColor(const CSSValue& stopColor, | 284 static Color resolveStopColor(const CSSValue& stopColor, |
| 284 const LayoutObject& object) { | 285 const LayoutObject& object) { |
| 285 return object.document().textLinkColors().colorFromCSSValue( | 286 return object.document().textLinkColors().colorFromCSSValue( |
| 286 stopColor, object.resolveColor(CSSPropertyColor)); | 287 stopColor, object.resolveColor(CSSPropertyColor)); |
| 287 } | 288 } |
| 288 | 289 |
| 289 void CSSGradientValue::addDeprecatedStops(GradientDesc& desc, | 290 void CSSGradientValue::addDeprecatedStops(GradientDesc& desc, |
| 290 const LayoutObject& object) { | 291 const LayoutObject& object) { |
| 291 ASSERT(m_gradientType == CSSDeprecatedLinearGradient || | 292 DCHECK(m_gradientType == CSSDeprecatedLinearGradient || |
| 292 m_gradientType == CSSDeprecatedRadialGradient); | 293 m_gradientType == CSSDeprecatedRadialGradient); |
| 293 | 294 |
| 294 if (!m_stopsSorted) { | 295 if (!m_stopsSorted) { |
| 295 if (m_stops.size()) | 296 if (m_stops.size()) |
| 296 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); | 297 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); |
| 297 m_stopsSorted = true; | 298 m_stopsSorted = true; |
| 298 } | 299 } |
| 299 | 300 |
| 300 for (const auto& stop : m_stops) { | 301 for (const auto& stop : m_stops) { |
| 301 float offset; | 302 float offset; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 323 if (stops.front().offset < 0 || stops.back().offset > 1) | 324 if (stops.front().offset < 0 || stops.back().offset > 1) |
| 324 return true; | 325 return true; |
| 325 | 326 |
| 326 return false; | 327 return false; |
| 327 } | 328 } |
| 328 | 329 |
| 329 // Redistribute the stops such that they fully cover [0 , 1] and add them to the | 330 // Redistribute the stops such that they fully cover [0 , 1] and add them to the |
| 330 // gradient. | 331 // gradient. |
| 331 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, | 332 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, |
| 332 CSSGradientValue::GradientDesc& desc) { | 333 CSSGradientValue::GradientDesc& desc) { |
| 333 ASSERT(stops.size() > 1); | 334 DCHECK_GT(stops.size(), 1u); |
| 334 | 335 |
| 335 const float firstOffset = stops.front().offset; | 336 const float firstOffset = stops.front().offset; |
| 336 const float lastOffset = stops.back().offset; | 337 const float lastOffset = stops.back().offset; |
| 337 const float span = lastOffset - firstOffset; | 338 const float span = lastOffset - firstOffset; |
| 338 | 339 |
| 339 if (fabs(span) < std::numeric_limits<float>::epsilon()) { | 340 if (fabs(span) < std::numeric_limits<float>::epsilon()) { |
| 340 // All stops are coincident -> use a single clamped offset value. | 341 // All stops are coincident -> use a single clamped offset value. |
| 341 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); | 342 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); |
| 342 | 343 |
| 343 // For repeating gradients, a coincident stop set defines a solid-color | 344 // For repeating gradients, a coincident stop set defines a solid-color |
| 344 // image with the color of the last color-stop in the rule. | 345 // image with the color of the last color-stop in the rule. |
| 345 // For non-repeating gradients, both the first color and the last color can | 346 // For non-repeating gradients, both the first color and the last color can |
| 346 // be significant (padding on both sides of the offset). | 347 // be significant (padding on both sides of the offset). |
| 347 if (desc.spreadMethod != SpreadMethodRepeat) | 348 if (desc.spreadMethod != SpreadMethodRepeat) |
| 348 desc.stops.emplace_back(clampedOffset, stops.front().color); | 349 desc.stops.emplace_back(clampedOffset, stops.front().color); |
| 349 desc.stops.emplace_back(clampedOffset, stops.back().color); | 350 desc.stops.emplace_back(clampedOffset, stops.back().color); |
| 350 | 351 |
| 351 return false; | 352 return false; |
| 352 } | 353 } |
| 353 | 354 |
| 354 ASSERT(span > 0); | 355 DCHECK_GT(span, 0); |
| 355 | 356 |
| 356 for (size_t i = 0; i < stops.size(); ++i) { | 357 for (size_t i = 0; i < stops.size(); ++i) { |
| 357 const float normalizedOffset = (stops[i].offset - firstOffset) / span; | 358 const float normalizedOffset = (stops[i].offset - firstOffset) / span; |
| 358 | 359 |
| 359 // stop offsets should be monotonically increasing in [0 , 1] | 360 // stop offsets should be monotonically increasing in [0 , 1] |
| 360 ASSERT(normalizedOffset >= 0 && normalizedOffset <= 1); | 361 DCHECK_GE(normalizedOffset, 0); |
| 361 ASSERT(i == 0 || | 362 DCHECK_LE(normalizedOffset, 1); |
| 363 DCHECK(i == 0 || |
| 362 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); | 364 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); |
| 363 | 365 |
| 364 desc.stops.emplace_back(normalizedOffset, stops[i].color); | 366 desc.stops.emplace_back(normalizedOffset, stops[i].color); |
| 365 } | 367 } |
| 366 | 368 |
| 367 return true; | 369 return true; |
| 368 } | 370 } |
| 369 | 371 |
| 370 // Collapse all negative-offset stops to 0 and compute an interpolated color | 372 // Collapse all negative-offset stops to 0 and compute an interpolated color |
| 371 // value for that point. | 373 // value for that point. |
| 372 static void clampNegativeOffsets(Vector<GradientStop>& stops) { | 374 static void clampNegativeOffsets(Vector<GradientStop>& stops) { |
| 373 float lastNegativeOffset = 0; | 375 float lastNegativeOffset = 0; |
| 374 | 376 |
| 375 for (size_t i = 0; i < stops.size(); ++i) { | 377 for (size_t i = 0; i < stops.size(); ++i) { |
| 376 const float currentOffset = stops[i].offset; | 378 const float currentOffset = stops[i].offset; |
| 377 if (currentOffset >= 0) { | 379 if (currentOffset >= 0) { |
| 378 if (i > 0) { | 380 if (i > 0) { |
| 379 // We found the negative -> positive offset transition: compute an | 381 // We found the negative -> positive offset transition: compute an |
| 380 // interpolated color value for 0 and use it with the last clamped stop. | 382 // interpolated color value for 0 and use it with the last clamped stop. |
| 381 ASSERT(lastNegativeOffset < 0); | 383 DCHECK_LT(lastNegativeOffset, 0); |
| 382 float lerpRatio = | 384 float lerpRatio = |
| 383 -lastNegativeOffset / (currentOffset - lastNegativeOffset); | 385 -lastNegativeOffset / (currentOffset - lastNegativeOffset); |
| 384 stops[i - 1].color = | 386 stops[i - 1].color = |
| 385 blend(stops[i - 1].color, stops[i].color, lerpRatio); | 387 blend(stops[i - 1].color, stops[i].color, lerpRatio); |
| 386 } | 388 } |
| 387 | 389 |
| 388 break; | 390 break; |
| 389 } | 391 } |
| 390 | 392 |
| 391 // Clamp all negative stops to 0. | 393 // Clamp all negative stops to 0. |
| 392 stops[i].offset = 0; | 394 stops[i].offset = 0; |
| 393 lastNegativeOffset = currentOffset; | 395 lastNegativeOffset = currentOffset; |
| 394 } | 396 } |
| 395 } | 397 } |
| 396 | 398 |
| 397 // Update the linear gradient points to align with the given offset range. | 399 // Update the linear gradient points to align with the given offset range. |
| 398 static void adjustGradientPointsForOffsetRange( | 400 static void adjustGradientPointsForOffsetRange( |
| 399 CSSGradientValue::GradientDesc& desc, | 401 CSSGradientValue::GradientDesc& desc, |
| 400 float firstOffset, | 402 float firstOffset, |
| 401 float lastOffset) { | 403 float lastOffset) { |
| 402 ASSERT(firstOffset <= lastOffset); | 404 DCHECK_LE(firstOffset, lastOffset); |
| 403 | 405 |
| 404 const FloatPoint p0 = desc.p0; | 406 const FloatPoint p0 = desc.p0; |
| 405 const FloatPoint p1 = desc.p1; | 407 const FloatPoint p1 = desc.p1; |
| 406 const FloatSize d(p1 - p0); | 408 const FloatSize d(p1 - p0); |
| 407 | 409 |
| 408 // Linear offsets are relative to the [p0 , p1] segment. | 410 // Linear offsets are relative to the [p0 , p1] segment. |
| 409 desc.p0 = p0 + d * firstOffset; | 411 desc.p0 = p0 + d * firstOffset; |
| 410 desc.p1 = p0 + d * lastOffset; | 412 desc.p1 = p0 + d * lastOffset; |
| 411 } | 413 } |
| 412 | 414 |
| 413 // Update the radial gradient radii to align with the given offset range. | 415 // Update the radial gradient radii to align with the given offset range. |
| 414 static void adjustGradientRadiiForOffsetRange( | 416 static void adjustGradientRadiiForOffsetRange( |
| 415 CSSGradientValue::GradientDesc& desc, | 417 CSSGradientValue::GradientDesc& desc, |
| 416 float firstOffset, | 418 float firstOffset, |
| 417 float lastOffset) { | 419 float lastOffset) { |
| 418 ASSERT(firstOffset <= lastOffset); | 420 DCHECK_LE(firstOffset, lastOffset); |
| 419 | 421 |
| 420 // Radial offsets are relative to the [0 , endRadius] segment. | 422 // Radial offsets are relative to the [0 , endRadius] segment. |
| 421 float adjustedR0 = desc.r1 * firstOffset; | 423 float adjustedR0 = desc.r1 * firstOffset; |
| 422 float adjustedR1 = desc.r1 * lastOffset; | 424 float adjustedR1 = desc.r1 * lastOffset; |
| 423 ASSERT(adjustedR0 <= adjustedR1); | 425 DCHECK_LE(adjustedR0, adjustedR1); |
| 424 | |
| 425 // Unlike linear gradients (where we can adjust the points arbitrarily), | 426 // Unlike linear gradients (where we can adjust the points arbitrarily), |
| 426 // we cannot let our radii turn negative here. | 427 // we cannot let our radii turn negative here. |
| 427 if (adjustedR0 < 0) { | 428 if (adjustedR0 < 0) { |
| 428 // For the non-repeat case, this can never happen: clampNegativeOffsets() | 429 // For the non-repeat case, this can never happen: clampNegativeOffsets() |
| 429 // ensures we don't have to deal with negative offsets at this point. | 430 // ensures we don't have to deal with negative offsets at this point. |
| 431 |
| 430 DCHECK_EQ(desc.spreadMethod, SpreadMethodRepeat); | 432 DCHECK_EQ(desc.spreadMethod, SpreadMethodRepeat); |
| 431 | 433 |
| 432 // When in repeat mode, we deal with it by repositioning both radii in the | 434 // When in repeat mode, we deal with it by repositioning both radii in the |
| 433 // positive domain - shifting them by a multiple of the radius span (which | 435 // positive domain - shifting them by a multiple of the radius span (which |
| 434 // is the period of our repeating gradient -> hence no visible side | 436 // is the period of our repeating gradient -> hence no visible side |
| 435 // effects). | 437 // effects). |
| 436 const float radiusSpan = adjustedR1 - adjustedR0; | 438 const float radiusSpan = adjustedR1 - adjustedR0; |
| 437 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); | 439 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); |
| 438 adjustedR0 += shiftToPositive; | 440 adjustedR0 += shiftToPositive; |
| 439 adjustedR1 += shiftToPositive; | 441 adjustedR1 += shiftToPositive; |
| 440 } | 442 } |
| 441 ASSERT(adjustedR0 >= 0); | 443 DCHECK_GE(adjustedR0, 0); |
| 442 ASSERT(adjustedR1 >= adjustedR0); | 444 DCHECK_GE(adjustedR1, adjustedR0); |
| 443 | 445 |
| 444 desc.r0 = adjustedR0; | 446 desc.r0 = adjustedR0; |
| 445 desc.r1 = adjustedR1; | 447 desc.r1 = adjustedR1; |
| 446 } | 448 } |
| 447 | 449 |
| 448 void CSSGradientValue::addStops(CSSGradientValue::GradientDesc& desc, | 450 void CSSGradientValue::addStops(CSSGradientValue::GradientDesc& desc, |
| 449 const CSSToLengthConversionData& conversionData, | 451 const CSSToLengthConversionData& conversionData, |
| 450 const LayoutObject& object) { | 452 const LayoutObject& object) { |
| 451 if (m_gradientType == CSSDeprecatedLinearGradient || | 453 if (m_gradientType == CSSDeprecatedLinearGradient || |
| 452 m_gradientType == CSSDeprecatedRadialGradient) { | 454 m_gradientType == CSSDeprecatedRadialGradient) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 if (stop.m_offset->isLength()) | 494 if (stop.m_offset->isLength()) |
| 493 length = stop.m_offset->computeLength<float>(conversionData); | 495 length = stop.m_offset->computeLength<float>(conversionData); |
| 494 else | 496 else |
| 495 length = stop.m_offset->cssCalcValue() | 497 length = stop.m_offset->cssCalcValue() |
| 496 ->toCalcValue(conversionData) | 498 ->toCalcValue(conversionData) |
| 497 ->evaluate(gradientLength); | 499 ->evaluate(gradientLength); |
| 498 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; | 500 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; |
| 499 } else if (stop.m_offset->isAngle()) { | 501 } else if (stop.m_offset->isAngle()) { |
| 500 stops[i].offset = stop.m_offset->computeDegrees() / 360.0f; | 502 stops[i].offset = stop.m_offset->computeDegrees() / 360.0f; |
| 501 } else { | 503 } else { |
| 502 ASSERT_NOT_REACHED(); | 504 NOTREACHED(); |
| 503 stops[i].offset = 0; | 505 stops[i].offset = 0; |
| 504 } | 506 } |
| 505 stops[i].specified = true; | 507 stops[i].specified = true; |
| 506 } else { | 508 } else { |
| 507 // If the first color-stop does not have a position, its position defaults | 509 // If the first color-stop does not have a position, its position defaults |
| 508 // to 0%. If the last color-stop does not have a position, its position | 510 // to 0%. If the last color-stop does not have a position, its position |
| 509 // defaults to 100%. | 511 // defaults to 100%. |
| 510 if (!i) { | 512 if (!i) { |
| 511 stops[i].offset = 0; | 513 stops[i].offset = 0; |
| 512 stops[i].specified = true; | 514 stops[i].specified = true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 525 --prevSpecifiedIndex) { | 527 --prevSpecifiedIndex) { |
| 526 if (stops[prevSpecifiedIndex].specified) | 528 if (stops[prevSpecifiedIndex].specified) |
| 527 break; | 529 break; |
| 528 } | 530 } |
| 529 | 531 |
| 530 if (stops[i].offset < stops[prevSpecifiedIndex].offset) | 532 if (stops[i].offset < stops[prevSpecifiedIndex].offset) |
| 531 stops[i].offset = stops[prevSpecifiedIndex].offset; | 533 stops[i].offset = stops[prevSpecifiedIndex].offset; |
| 532 } | 534 } |
| 533 } | 535 } |
| 534 | 536 |
| 535 ASSERT(stops.front().specified && stops.back().specified); | 537 DCHECK(stops.front().specified); |
| 538 DCHECK(stops.back().specified); |
| 536 | 539 |
| 537 // If any color-stop still does not have a position, then, for each run of | 540 // If any color-stop still does not have a position, then, for each run of |
| 538 // adjacent color-stops without positions, set their positions so that they | 541 // adjacent color-stops without positions, set their positions so that they |
| 539 // are evenly spaced between the preceding and following color-stops with | 542 // are evenly spaced between the preceding and following color-stops with |
| 540 // positions. | 543 // positions. |
| 541 if (numStops > 2) { | 544 if (numStops > 2) { |
| 542 size_t unspecifiedRunStart = 0; | 545 size_t unspecifiedRunStart = 0; |
| 543 bool inUnspecifiedRun = false; | 546 bool inUnspecifiedRun = false; |
| 544 | 547 |
| 545 for (size_t i = 0; i < numStops; ++i) { | 548 for (size_t i = 0; i < numStops; ++i) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 558 for (size_t j = unspecifiedRunStart; j < unspecifiedRunEnd; ++j) | 561 for (size_t j = unspecifiedRunStart; j < unspecifiedRunEnd; ++j) |
| 559 stops[j].offset = | 562 stops[j].offset = |
| 560 lastSpecifiedOffset + (j - unspecifiedRunStart + 1) * delta; | 563 lastSpecifiedOffset + (j - unspecifiedRunStart + 1) * delta; |
| 561 } | 564 } |
| 562 | 565 |
| 563 inUnspecifiedRun = false; | 566 inUnspecifiedRun = false; |
| 564 } | 567 } |
| 565 } | 568 } |
| 566 } | 569 } |
| 567 | 570 |
| 568 ASSERT(stops.size() == m_stops.size()); | 571 DCHECK_EQ(stops.size(), m_stops.size()); |
| 569 if (hasHints) { | 572 if (hasHints) { |
| 570 replaceColorHintsWithColorStops(stops, m_stops); | 573 replaceColorHintsWithColorStops(stops, m_stops); |
| 571 } | 574 } |
| 572 | 575 |
| 573 // At this point we have a fully resolved set of stops. Time to perform | 576 // At this point we have a fully resolved set of stops. Time to perform |
| 574 // adjustments for repeat gradients and degenerate values if needed. | 577 // adjustments for repeat gradients and degenerate values if needed. |
| 575 // Note: the normalization trick doesn't work for conic gradients, because | 578 // Note: the normalization trick doesn't work for conic gradients, because |
| 576 // the underlying Skia implementation doesn't support tiling. | 579 // the underlying Skia implementation doesn't support tiling. |
| 577 if (isConicGradientValue() || !requiresStopsNormalization(stops, desc)) { | 580 if (isConicGradientValue() || !requiresStopsNormalization(stops, desc)) { |
| 578 // No normalization required, just add the current stops. | 581 // No normalization required, just add the current stops. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 // moved origin and the fact that we're in drawing space (+y = down). | 854 // moved origin and the fact that we're in drawing space (+y = down). |
| 852 secondPoint.set(halfWidth + endX, halfHeight - endY); | 855 secondPoint.set(halfWidth + endX, halfHeight - endY); |
| 853 // Reflect around the center for the start point. | 856 // Reflect around the center for the start point. |
| 854 firstPoint.set(halfWidth - endX, halfHeight + endY); | 857 firstPoint.set(halfWidth - endX, halfHeight + endY); |
| 855 } | 858 } |
| 856 | 859 |
| 857 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient( | 860 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient( |
| 858 const CSSToLengthConversionData& conversionData, | 861 const CSSToLengthConversionData& conversionData, |
| 859 const IntSize& size, | 862 const IntSize& size, |
| 860 const LayoutObject& object) { | 863 const LayoutObject& object) { |
| 861 ASSERT(!size.isEmpty()); | 864 DCHECK(!size.isEmpty()); |
| 862 | 865 |
| 863 FloatPoint firstPoint; | 866 FloatPoint firstPoint; |
| 864 FloatPoint secondPoint; | 867 FloatPoint secondPoint; |
| 865 if (m_angle) { | 868 if (m_angle) { |
| 866 float angle = m_angle->computeDegrees(); | 869 float angle = m_angle->computeDegrees(); |
| 867 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType); | 870 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType); |
| 868 } else { | 871 } else { |
| 869 switch (m_gradientType) { | 872 switch (m_gradientType) { |
| 870 case CSSDeprecatedLinearGradient: | 873 case CSSDeprecatedLinearGradient: |
| 871 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), | 874 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), | 912 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), |
| 910 conversionData, size); | 913 conversionData, size); |
| 911 if (m_firstX) | 914 if (m_firstX) |
| 912 firstPoint.setX(size.width() - secondPoint.x()); | 915 firstPoint.setX(size.width() - secondPoint.x()); |
| 913 if (m_firstY) | 916 if (m_firstY) |
| 914 firstPoint.setY(size.height() - secondPoint.y()); | 917 firstPoint.setY(size.height() - secondPoint.y()); |
| 915 } else | 918 } else |
| 916 secondPoint.setY(size.height()); | 919 secondPoint.setY(size.height()); |
| 917 break; | 920 break; |
| 918 default: | 921 default: |
| 919 ASSERT_NOT_REACHED(); | 922 NOTREACHED(); |
| 920 } | 923 } |
| 921 } | 924 } |
| 922 | 925 |
| 923 GradientDesc desc(firstPoint, secondPoint, | 926 GradientDesc desc(firstPoint, secondPoint, |
| 924 m_repeating ? SpreadMethodRepeat : SpreadMethodPad); | 927 m_repeating ? SpreadMethodRepeat : SpreadMethodPad); |
| 925 addStops(desc, conversionData, object); | 928 addStops(desc, conversionData, object); |
| 926 | 929 |
| 927 RefPtr<Gradient> gradient = | 930 RefPtr<Gradient> gradient = |
| 928 Gradient::createLinear(desc.p0, desc.p1, desc.spreadMethod, | 931 Gradient::createLinear(desc.p0, desc.p1, desc.spreadMethod, |
| 929 Gradient::ColorInterpolation::Premultiplied); | 932 Gradient::ColorInterpolation::Premultiplied); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 float dy1 = clampTo<float>(fabs(point.y())); | 1146 float dy1 = clampTo<float>(fabs(point.y())); |
| 1144 float dx2 = clampTo<float>(fabs(point.x() - size.width())); | 1147 float dx2 = clampTo<float>(fabs(point.x() - size.width())); |
| 1145 float dy2 = clampTo<float>(fabs(point.y() - size.height())); | 1148 float dy2 = clampTo<float>(fabs(point.y() - size.height())); |
| 1146 | 1149 |
| 1147 float dx = compare(dx1, dx2) ? dx1 : dx2; | 1150 float dx = compare(dx1, dx2) ? dx1 : dx2; |
| 1148 float dy = compare(dy1, dy2) ? dy1 : dy2; | 1151 float dy = compare(dy1, dy2) ? dy1 : dy2; |
| 1149 | 1152 |
| 1150 if (shape == CircleEndShape) | 1153 if (shape == CircleEndShape) |
| 1151 return compare(dx, dy) ? FloatSize(dx, dx) : FloatSize(dy, dy); | 1154 return compare(dx, dy) ? FloatSize(dx, dx) : FloatSize(dy, dy); |
| 1152 | 1155 |
| 1153 ASSERT(shape == EllipseEndShape); | 1156 DCHECK_EQ(shape, EllipseEndShape); |
| 1154 return FloatSize(dx, dy); | 1157 return FloatSize(dx, dy); |
| 1155 } | 1158 } |
| 1156 | 1159 |
| 1157 // Compute the radius of an ellipse with center at 0,0 which passes through p, | 1160 // Compute the radius of an ellipse with center at 0,0 which passes through p, |
| 1158 // and has width/height given by aspectRatio. | 1161 // and has width/height given by aspectRatio. |
| 1159 inline FloatSize ellipseRadius(const FloatPoint& p, float aspectRatio) { | 1162 inline FloatSize ellipseRadius(const FloatPoint& p, float aspectRatio) { |
| 1160 // If the aspectRatio is 0 or infinite, the ellipse is completely flat. | 1163 // If the aspectRatio is 0 or infinite, the ellipse is completely flat. |
| 1161 // TODO(sashab): Implement Degenerate Radial Gradients, see crbug.com/635727. | 1164 // TODO(sashab): Implement Degenerate Radial Gradients, see crbug.com/635727. |
| 1162 if (aspectRatio == 0 || std::isinf(aspectRatio)) | 1165 if (aspectRatio == 0 || std::isinf(aspectRatio)) |
| 1163 return FloatSize(0, 0); | 1166 return FloatSize(0, 0); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1185 float newDistance = (point - corners[i]).diagonalLength(); | 1188 float newDistance = (point - corners[i]).diagonalLength(); |
| 1186 if (compare(newDistance, distance)) { | 1189 if (compare(newDistance, distance)) { |
| 1187 cornerIndex = i; | 1190 cornerIndex = i; |
| 1188 distance = newDistance; | 1191 distance = newDistance; |
| 1189 } | 1192 } |
| 1190 } | 1193 } |
| 1191 | 1194 |
| 1192 if (shape == CircleEndShape) | 1195 if (shape == CircleEndShape) |
| 1193 return FloatSize(distance, distance); | 1196 return FloatSize(distance, distance); |
| 1194 | 1197 |
| 1195 ASSERT(shape == EllipseEndShape); | 1198 DCHECK_EQ(shape, EllipseEndShape); |
| 1196 // If the end shape is an ellipse, the gradient-shape has the same ratio of | 1199 // If the end shape is an ellipse, the gradient-shape has the same ratio of |
| 1197 // width to height that it would if closest-side or farthest-side were | 1200 // width to height that it would if closest-side or farthest-side were |
| 1198 // specified, as appropriate. | 1201 // specified, as appropriate. |
| 1199 const FloatSize sideRadius = | 1202 const FloatSize sideRadius = |
| 1200 radiusToSide(point, size, EllipseEndShape, compare); | 1203 radiusToSide(point, size, EllipseEndShape, compare); |
| 1201 | 1204 |
| 1202 return ellipseRadius(FloatPoint(corners[cornerIndex] - point), | 1205 return ellipseRadius(FloatPoint(corners[cornerIndex] - point), |
| 1203 sideRadius.aspectRatio()); | 1206 sideRadius.aspectRatio()); |
| 1204 } | 1207 } |
| 1205 | 1208 |
| 1206 } // anonymous namespace | 1209 } // anonymous namespace |
| 1207 | 1210 |
| 1208 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient( | 1211 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient( |
| 1209 const CSSToLengthConversionData& conversionData, | 1212 const CSSToLengthConversionData& conversionData, |
| 1210 const IntSize& size, | 1213 const IntSize& size, |
| 1211 const LayoutObject& object) { | 1214 const LayoutObject& object) { |
| 1212 ASSERT(!size.isEmpty()); | 1215 DCHECK(!size.isEmpty()); |
| 1213 | 1216 |
| 1214 FloatPoint firstPoint = | 1217 FloatPoint firstPoint = |
| 1215 computeEndPoint(m_firstX.get(), m_firstY.get(), conversionData, size); | 1218 computeEndPoint(m_firstX.get(), m_firstY.get(), conversionData, size); |
| 1216 if (!m_firstX) | 1219 if (!m_firstX) |
| 1217 firstPoint.setX(size.width() / 2); | 1220 firstPoint.setX(size.width() / 2); |
| 1218 if (!m_firstY) | 1221 if (!m_firstY) |
| 1219 firstPoint.setY(size.height() / 2); | 1222 firstPoint.setY(size.height() / 2); |
| 1220 | 1223 |
| 1221 FloatPoint secondPoint = | 1224 FloatPoint secondPoint = |
| 1222 computeEndPoint(m_secondX.get(), m_secondY.get(), conversionData, size); | 1225 computeEndPoint(m_secondX.get(), m_secondY.get(), conversionData, size); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 dataEquivalent(m_fromAngle, other.m_fromAngle) && | 1413 dataEquivalent(m_fromAngle, other.m_fromAngle) && |
| 1411 m_stops == other.m_stops; | 1414 m_stops == other.m_stops; |
| 1412 } | 1415 } |
| 1413 | 1416 |
| 1414 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { | 1417 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { |
| 1415 visitor->trace(m_fromAngle); | 1418 visitor->trace(m_fromAngle); |
| 1416 CSSGradientValue::traceAfterDispatch(visitor); | 1419 CSSGradientValue::traceAfterDispatch(visitor); |
| 1417 } | 1420 } |
| 1418 | 1421 |
| 1419 } // namespace blink | 1422 } // namespace blink |
| OLD | NEW |