Chromium Code Reviews| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 | 144 |
| 145 int indexOffset = 0; | 145 int indexOffset = 0; |
| 146 | 146 |
| 147 // The first and the last color stops cannot be color hints. | 147 // The first and the last color stops cannot be color hints. |
| 148 for (size_t i = 1; i < cssGradientStops.size() - 1; ++i) { | 148 for (size_t i = 1; i < cssGradientStops.size() - 1; ++i) { |
| 149 if (!cssGradientStops[i].isHint()) | 149 if (!cssGradientStops[i].isHint()) |
| 150 continue; | 150 continue; |
| 151 | 151 |
| 152 // The current index of the stops vector. | 152 // The current index of the stops vector. |
| 153 size_t x = i + indexOffset; | 153 size_t x = i + indexOffset; |
| 154 ASSERT(x >= 1); | 154 DCHECK_GE(x, static_cast<unsigned>(1)); |
|
tkent
2017/03/28 14:44:55
static_cast<unsigned>(1) -> 1u
nikhil.sahni
2017/03/30 12:17:57
Done.
| |
| 155 | 155 |
| 156 // offsetLeft offset offsetRight | 156 // offsetLeft offset offsetRight |
| 157 // |-------------------|---------------------------------| | 157 // |-------------------|---------------------------------| |
| 158 // leftDist rightDist | 158 // leftDist rightDist |
| 159 | 159 |
| 160 float offsetLeft = stops[x - 1].offset; | 160 float offsetLeft = stops[x - 1].offset; |
| 161 float offsetRight = stops[x + 1].offset; | 161 float offsetRight = stops[x + 1].offset; |
| 162 float offset = stops[x].offset; | 162 float offset = stops[x].offset; |
| 163 float leftDist = offset - offsetLeft; | 163 float leftDist = offset - offsetLeft; |
| 164 float rightDist = offsetRight - offset; | 164 float rightDist = offsetRight - offset; |
| 165 float totalDist = offsetRight - offsetLeft; | 165 float totalDist = offsetRight - offsetLeft; |
| 166 | 166 |
| 167 Color leftColor = stops[x - 1].color; | 167 Color leftColor = stops[x - 1].color; |
| 168 Color rightColor = stops[x + 1].color; | 168 Color rightColor = stops[x + 1].color; |
| 169 | 169 |
| 170 ASSERT(offsetLeft <= offset && offset <= offsetRight); | 170 DCHECK_LE(offsetLeft, offset); |
| 171 DCHECK_LE(offset, offsetRight); | |
| 171 | 172 |
| 172 if (WebCoreFloatNearlyEqual(leftDist, rightDist)) { | 173 if (WebCoreFloatNearlyEqual(leftDist, rightDist)) { |
| 173 stops.remove(x); | 174 stops.remove(x); |
| 174 --indexOffset; | 175 --indexOffset; |
| 175 continue; | 176 continue; |
| 176 } | 177 } |
| 177 | 178 |
| 178 if (WebCoreFloatNearlyEqual(leftDist, .0f)) { | 179 if (WebCoreFloatNearlyEqual(leftDist, .0f)) { |
| 179 stops[x].color = rightColor; | 180 stops[x].color = rightColor; |
| 180 continue; | 181 continue; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 } | 219 } |
| 219 | 220 |
| 220 static Color resolveStopColor(const CSSValue& stopColor, | 221 static Color resolveStopColor(const CSSValue& stopColor, |
| 221 const LayoutObject& object) { | 222 const LayoutObject& object) { |
| 222 return object.document().textLinkColors().colorFromCSSValue( | 223 return object.document().textLinkColors().colorFromCSSValue( |
| 223 stopColor, object.resolveColor(CSSPropertyColor)); | 224 stopColor, object.resolveColor(CSSPropertyColor)); |
| 224 } | 225 } |
| 225 | 226 |
| 226 void CSSGradientValue::addDeprecatedStops(Gradient* gradient, | 227 void CSSGradientValue::addDeprecatedStops(Gradient* gradient, |
| 227 const LayoutObject& object) { | 228 const LayoutObject& object) { |
| 228 ASSERT(m_gradientType == CSSDeprecatedLinearGradient || | 229 DCHECK(m_gradientType == CSSDeprecatedLinearGradient || |
| 229 m_gradientType == CSSDeprecatedRadialGradient); | 230 m_gradientType == CSSDeprecatedRadialGradient); |
| 230 | 231 |
| 231 if (!m_stopsSorted) { | 232 if (!m_stopsSorted) { |
| 232 if (m_stops.size()) | 233 if (m_stops.size()) |
| 233 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); | 234 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); |
| 234 m_stopsSorted = true; | 235 m_stopsSorted = true; |
| 235 } | 236 } |
| 236 | 237 |
| 237 for (const auto& stop : m_stops) { | 238 for (const auto& stop : m_stops) { |
| 238 float offset; | 239 float offset; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 260 if (stops.front().offset < 0 || stops.back().offset > 1) | 261 if (stops.front().offset < 0 || stops.back().offset > 1) |
| 261 return true; | 262 return true; |
| 262 | 263 |
| 263 return false; | 264 return false; |
| 264 } | 265 } |
| 265 | 266 |
| 266 // Redistribute the stops such that they fully cover [0 , 1] and add them to the | 267 // Redistribute the stops such that they fully cover [0 , 1] and add them to the |
| 267 // gradient. | 268 // gradient. |
| 268 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, | 269 static bool normalizeAndAddStops(const Vector<GradientStop>& stops, |
| 269 Gradient* gradient) { | 270 Gradient* gradient) { |
| 270 ASSERT(stops.size() > 1); | 271 DCHECK_GT(stops.size(), static_cast<unsigned>(1)); |
|
tkent
2017/03/28 14:44:55
static_cast<unsigned>(1) -> 1u
nikhil.sahni
2017/03/30 12:17:57
Done.
| |
| 271 | 272 |
| 272 const float firstOffset = stops.front().offset; | 273 const float firstOffset = stops.front().offset; |
| 273 const float lastOffset = stops.back().offset; | 274 const float lastOffset = stops.back().offset; |
| 274 const float span = lastOffset - firstOffset; | 275 const float span = lastOffset - firstOffset; |
| 275 | 276 |
| 276 if (fabs(span) < std::numeric_limits<float>::epsilon()) { | 277 if (fabs(span) < std::numeric_limits<float>::epsilon()) { |
| 277 // All stops are coincident -> use a single clamped offset value. | 278 // All stops are coincident -> use a single clamped offset value. |
| 278 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); | 279 const float clampedOffset = std::min(std::max(firstOffset, 0.f), 1.f); |
| 279 | 280 |
| 280 // For repeating gradients, a coincident stop set defines a solid-color | 281 // For repeating gradients, a coincident stop set defines a solid-color |
| 281 // image with the color of the last color-stop in the rule. | 282 // 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 | 283 // For non-repeating gradients, both the first color and the last color can |
| 283 // be significant (padding on both sides of the offset). | 284 // be significant (padding on both sides of the offset). |
| 284 if (gradient->spreadMethod() != SpreadMethodRepeat) | 285 if (gradient->spreadMethod() != SpreadMethodRepeat) |
| 285 gradient->addColorStop(clampedOffset, stops.front().color); | 286 gradient->addColorStop(clampedOffset, stops.front().color); |
| 286 gradient->addColorStop(clampedOffset, stops.back().color); | 287 gradient->addColorStop(clampedOffset, stops.back().color); |
| 287 | 288 |
| 288 return false; | 289 return false; |
| 289 } | 290 } |
| 290 | 291 |
| 291 ASSERT(span > 0); | 292 DCHECK_GT(span, 0); |
| 292 | 293 |
| 293 for (size_t i = 0; i < stops.size(); ++i) { | 294 for (size_t i = 0; i < stops.size(); ++i) { |
| 294 const float normalizedOffset = (stops[i].offset - firstOffset) / span; | 295 const float normalizedOffset = (stops[i].offset - firstOffset) / span; |
| 295 | 296 |
| 296 // stop offsets should be monotonically increasing in [0 , 1] | 297 // stop offsets should be monotonically increasing in [0 , 1] |
| 297 ASSERT(normalizedOffset >= 0 && normalizedOffset <= 1); | 298 DCHECK_GE(normalizedOffset, 0); |
| 298 ASSERT(i == 0 || | 299 DCHECK_LE(normalizedOffset, 1); |
| 300 DCHECK(i == 0 || | |
| 299 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); | 301 normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); |
| 300 | 302 |
| 301 gradient->addColorStop(normalizedOffset, stops[i].color); | 303 gradient->addColorStop(normalizedOffset, stops[i].color); |
| 302 } | 304 } |
| 303 | 305 |
| 304 return true; | 306 return true; |
| 305 } | 307 } |
| 306 | 308 |
| 307 // Collapse all negative-offset stops to 0 and compute an interpolated color | 309 // Collapse all negative-offset stops to 0 and compute an interpolated color |
| 308 // value for that point. | 310 // value for that point. |
| 309 static void clampNegativeOffsets(Vector<GradientStop>& stops) { | 311 static void clampNegativeOffsets(Vector<GradientStop>& stops) { |
| 310 float lastNegativeOffset = 0; | 312 float lastNegativeOffset = 0; |
| 311 | 313 |
| 312 for (size_t i = 0; i < stops.size(); ++i) { | 314 for (size_t i = 0; i < stops.size(); ++i) { |
| 313 const float currentOffset = stops[i].offset; | 315 const float currentOffset = stops[i].offset; |
| 314 if (currentOffset >= 0) { | 316 if (currentOffset >= 0) { |
| 315 if (i > 0) { | 317 if (i > 0) { |
| 316 // We found the negative -> positive offset transition: compute an | 318 // We found the negative -> positive offset transition: compute an |
| 317 // interpolated color value for 0 and use it with the last clamped stop. | 319 // interpolated color value for 0 and use it with the last clamped stop. |
| 318 ASSERT(lastNegativeOffset < 0); | 320 DCHECK_LT(lastNegativeOffset, 0); |
| 319 float lerpRatio = | 321 float lerpRatio = |
| 320 -lastNegativeOffset / (currentOffset - lastNegativeOffset); | 322 -lastNegativeOffset / (currentOffset - lastNegativeOffset); |
| 321 stops[i - 1].color = | 323 stops[i - 1].color = |
| 322 blend(stops[i - 1].color, stops[i].color, lerpRatio); | 324 blend(stops[i - 1].color, stops[i].color, lerpRatio); |
| 323 } | 325 } |
| 324 | 326 |
| 325 break; | 327 break; |
| 326 } | 328 } |
| 327 | 329 |
| 328 // Clamp all negative stops to 0. | 330 // Clamp all negative stops to 0. |
| 329 stops[i].offset = 0; | 331 stops[i].offset = 0; |
| 330 lastNegativeOffset = currentOffset; | 332 lastNegativeOffset = currentOffset; |
| 331 } | 333 } |
| 332 } | 334 } |
| 333 | 335 |
| 334 // Update the linear gradient points to align with the given offset range. | 336 // Update the linear gradient points to align with the given offset range. |
| 335 static void adjustGradientPointsForOffsetRange(Gradient* gradient, | 337 static void adjustGradientPointsForOffsetRange(Gradient* gradient, |
| 336 float firstOffset, | 338 float firstOffset, |
| 337 float lastOffset) { | 339 float lastOffset) { |
| 338 ASSERT(!gradient->isRadial()); | 340 DCHECK(!gradient->isRadial()); |
| 339 ASSERT(firstOffset <= lastOffset); | 341 DCHECK(firstOffset <= lastOffset); |
|
tkent
2017/03/28 14:44:55
Use DCHECK_LE
nikhil.sahni
2017/03/30 12:17:57
Done.
| |
| 340 | 342 |
| 341 const FloatPoint p0 = gradient->p0(); | 343 const FloatPoint p0 = gradient->p0(); |
| 342 const FloatPoint p1 = gradient->p1(); | 344 const FloatPoint p1 = gradient->p1(); |
| 343 const FloatSize d(p1 - p0); | 345 const FloatSize d(p1 - p0); |
| 344 | 346 |
| 345 // Linear offsets are relative to the [p0 , p1] segment. | 347 // Linear offsets are relative to the [p0 , p1] segment. |
| 346 gradient->setP0(p0 + d * firstOffset); | 348 gradient->setP0(p0 + d * firstOffset); |
| 347 gradient->setP1(p0 + d * lastOffset); | 349 gradient->setP1(p0 + d * lastOffset); |
| 348 } | 350 } |
| 349 | 351 |
| 350 // Update the radial gradient radii to align with the given offset range. | 352 // Update the radial gradient radii to align with the given offset range. |
| 351 static void adjustGradientRadiiForOffsetRange(Gradient* gradient, | 353 static void adjustGradientRadiiForOffsetRange(Gradient* gradient, |
| 352 float firstOffset, | 354 float firstOffset, |
| 353 float lastOffset) { | 355 float lastOffset) { |
| 354 ASSERT(gradient->isRadial()); | 356 DCHECK(gradient->isRadial()); |
| 355 ASSERT(firstOffset <= lastOffset); | 357 DCHECK_LE(firstOffset, lastOffset); |
| 356 | 358 |
| 357 // Radial offsets are relative to the [0 , endRadius] segment. | 359 // Radial offsets are relative to the [0 , endRadius] segment. |
| 358 float adjustedR0 = gradient->endRadius() * firstOffset; | 360 float adjustedR0 = gradient->endRadius() * firstOffset; |
| 359 float adjustedR1 = gradient->endRadius() * lastOffset; | 361 float adjustedR1 = gradient->endRadius() * lastOffset; |
| 360 ASSERT(adjustedR0 <= adjustedR1); | 362 DCHECK_LE(adjustedR0, adjustedR1); |
| 361 | 363 |
| 362 // Unlike linear gradients (where we can adjust the points arbitrarily), | 364 // Unlike linear gradients (where we can adjust the points arbitrarily), |
| 363 // we cannot let our radii turn negative here. | 365 // we cannot let our radii turn negative here. |
| 364 if (adjustedR0 < 0) { | 366 if (adjustedR0 < 0) { |
| 365 // For the non-repeat case, this can never happen: clampNegativeOffsets() | 367 // For the non-repeat case, this can never happen: clampNegativeOffsets() |
| 366 // ensures we don't have to deal with negative offsets at this point. | 368 // ensures we don't have to deal with negative offsets at this point. |
| 367 ASSERT(gradient->spreadMethod() == SpreadMethodRepeat); | 369 DCHECK_EQ(gradient->spreadMethod(), SpreadMethodRepeat); |
| 368 | 370 |
| 369 // When in repeat mode, we deal with it by repositioning both radii in the | 371 // 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 | 372 // positive domain - shifting them by a multiple of the radius span (which |
| 371 // is the period of our repeating gradient -> hence no visible side | 373 // is the period of our repeating gradient -> hence no visible side |
| 372 // effects). | 374 // effects). |
| 373 const float radiusSpan = adjustedR1 - adjustedR0; | 375 const float radiusSpan = adjustedR1 - adjustedR0; |
| 374 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); | 376 const float shiftToPositive = radiusSpan * ceilf(-adjustedR0 / radiusSpan); |
| 375 adjustedR0 += shiftToPositive; | 377 adjustedR0 += shiftToPositive; |
| 376 adjustedR1 += shiftToPositive; | 378 adjustedR1 += shiftToPositive; |
| 377 } | 379 } |
| 378 ASSERT(adjustedR0 >= 0); | 380 DCHECK_GE(adjustedR0, 0); |
| 379 ASSERT(adjustedR1 >= adjustedR0); | 381 DCHECK_GE(adjustedR1, adjustedR0); |
| 380 | 382 |
| 381 gradient->setStartRadius(adjustedR0); | 383 gradient->setStartRadius(adjustedR0); |
| 382 gradient->setEndRadius(adjustedR1); | 384 gradient->setEndRadius(adjustedR1); |
| 383 } | 385 } |
| 384 | 386 |
| 385 void CSSGradientValue::addStops(Gradient* gradient, | 387 void CSSGradientValue::addStops(Gradient* gradient, |
| 386 const CSSToLengthConversionData& conversionData, | 388 const CSSToLengthConversionData& conversionData, |
| 387 const LayoutObject& object) { | 389 const LayoutObject& object) { |
| 388 if (m_gradientType == CSSDeprecatedLinearGradient || | 390 if (m_gradientType == CSSDeprecatedLinearGradient || |
| 389 m_gradientType == CSSDeprecatedRadialGradient) { | 391 m_gradientType == CSSDeprecatedRadialGradient) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 stop.m_position->isCalculatedPercentageWithLength()) { | 423 stop.m_position->isCalculatedPercentageWithLength()) { |
| 422 float length; | 424 float length; |
| 423 if (stop.m_position->isLength()) | 425 if (stop.m_position->isLength()) |
| 424 length = stop.m_position->computeLength<float>(conversionData); | 426 length = stop.m_position->computeLength<float>(conversionData); |
| 425 else | 427 else |
| 426 length = stop.m_position->cssCalcValue() | 428 length = stop.m_position->cssCalcValue() |
| 427 ->toCalcValue(conversionData) | 429 ->toCalcValue(conversionData) |
| 428 ->evaluate(gradientLength); | 430 ->evaluate(gradientLength); |
| 429 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; | 431 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; |
| 430 } else { | 432 } else { |
| 431 ASSERT_NOT_REACHED(); | 433 NOTREACHED(); |
| 432 stops[i].offset = 0; | 434 stops[i].offset = 0; |
| 433 } | 435 } |
| 434 stops[i].specified = true; | 436 stops[i].specified = true; |
| 435 } else { | 437 } else { |
| 436 // If the first color-stop does not have a position, its position defaults | 438 // If the first color-stop does not have a position, its position defaults |
| 437 // to 0%. If the last color-stop does not have a position, its position | 439 // to 0%. If the last color-stop does not have a position, its position |
| 438 // defaults to 100%. | 440 // defaults to 100%. |
| 439 if (!i) { | 441 if (!i) { |
| 440 stops[i].offset = 0; | 442 stops[i].offset = 0; |
| 441 stops[i].specified = true; | 443 stops[i].specified = true; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 454 --prevSpecifiedIndex) { | 456 --prevSpecifiedIndex) { |
| 455 if (stops[prevSpecifiedIndex].specified) | 457 if (stops[prevSpecifiedIndex].specified) |
| 456 break; | 458 break; |
| 457 } | 459 } |
| 458 | 460 |
| 459 if (stops[i].offset < stops[prevSpecifiedIndex].offset) | 461 if (stops[i].offset < stops[prevSpecifiedIndex].offset) |
| 460 stops[i].offset = stops[prevSpecifiedIndex].offset; | 462 stops[i].offset = stops[prevSpecifiedIndex].offset; |
| 461 } | 463 } |
| 462 } | 464 } |
| 463 | 465 |
| 464 ASSERT(stops.front().specified && stops.back().specified); | 466 DCHECK(stops.front().specified); |
| 467 DCHECK(stops.back().specified); | |
| 465 | 468 |
| 466 // If any color-stop still does not have a position, then, for each run of | 469 // 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 | 470 // adjacent color-stops without positions, set their positions so that they |
| 468 // are evenly spaced between the preceding and following color-stops with | 471 // are evenly spaced between the preceding and following color-stops with |
| 469 // positions. | 472 // positions. |
| 470 if (numStops > 2) { | 473 if (numStops > 2) { |
| 471 size_t unspecifiedRunStart = 0; | 474 size_t unspecifiedRunStart = 0; |
| 472 bool inUnspecifiedRun = false; | 475 bool inUnspecifiedRun = false; |
| 473 | 476 |
| 474 for (size_t i = 0; i < numStops; ++i) { | 477 for (size_t i = 0; i < numStops; ++i) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 487 for (size_t j = unspecifiedRunStart; j < unspecifiedRunEnd; ++j) | 490 for (size_t j = unspecifiedRunStart; j < unspecifiedRunEnd; ++j) |
| 488 stops[j].offset = | 491 stops[j].offset = |
| 489 lastSpecifiedOffset + (j - unspecifiedRunStart + 1) * delta; | 492 lastSpecifiedOffset + (j - unspecifiedRunStart + 1) * delta; |
| 490 } | 493 } |
| 491 | 494 |
| 492 inUnspecifiedRun = false; | 495 inUnspecifiedRun = false; |
| 493 } | 496 } |
| 494 } | 497 } |
| 495 } | 498 } |
| 496 | 499 |
| 497 ASSERT(stops.size() == m_stops.size()); | 500 DCHECK_EQ(stops.size(), m_stops.size()); |
| 498 if (hasHints) { | 501 if (hasHints) { |
| 499 replaceColorHintsWithColorStops(stops, m_stops); | 502 replaceColorHintsWithColorStops(stops, m_stops); |
| 500 } | 503 } |
| 501 | 504 |
| 502 // At this point we have a fully resolved set of stops. Time to perform | 505 // At this point we have a fully resolved set of stops. Time to perform |
| 503 // adjustments for repeat gradients and degenerate values if needed. | 506 // adjustments for repeat gradients and degenerate values if needed. |
| 504 if (requiresStopsNormalization(stops, gradient)) { | 507 if (requiresStopsNormalization(stops, gradient)) { |
| 505 // Negative offsets are only an issue for non-repeating radial gradients: | 508 // Negative offsets are only an issue for non-repeating radial gradients: |
| 506 // linear gradient points can be repositioned arbitrarily, and for repeating | 509 // linear gradient points can be repositioned arbitrarily, and for repeating |
| 507 // radial gradients we shift the radii into equivalent positive values. | 510 // radial gradients we shift the radii into equivalent positive values. |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 // moved origin and the fact that we're in drawing space (+y = down). | 812 // moved origin and the fact that we're in drawing space (+y = down). |
| 810 secondPoint.set(halfWidth + endX, halfHeight - endY); | 813 secondPoint.set(halfWidth + endX, halfHeight - endY); |
| 811 // Reflect around the center for the start point. | 814 // Reflect around the center for the start point. |
| 812 firstPoint.set(halfWidth - endX, halfHeight + endY); | 815 firstPoint.set(halfWidth - endX, halfHeight + endY); |
| 813 } | 816 } |
| 814 | 817 |
| 815 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient( | 818 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient( |
| 816 const CSSToLengthConversionData& conversionData, | 819 const CSSToLengthConversionData& conversionData, |
| 817 const IntSize& size, | 820 const IntSize& size, |
| 818 const LayoutObject& object) { | 821 const LayoutObject& object) { |
| 819 ASSERT(!size.isEmpty()); | 822 DCHECK(!size.isEmpty()); |
| 820 | 823 |
| 821 FloatPoint firstPoint; | 824 FloatPoint firstPoint; |
| 822 FloatPoint secondPoint; | 825 FloatPoint secondPoint; |
| 823 if (m_angle) { | 826 if (m_angle) { |
| 824 float angle = m_angle->computeDegrees(); | 827 float angle = m_angle->computeDegrees(); |
| 825 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType); | 828 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType); |
| 826 } else { | 829 } else { |
| 827 switch (m_gradientType) { | 830 switch (m_gradientType) { |
| 828 case CSSDeprecatedLinearGradient: | 831 case CSSDeprecatedLinearGradient: |
| 829 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), | 832 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 867 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), | 870 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), |
| 868 conversionData, size); | 871 conversionData, size); |
| 869 if (m_firstX) | 872 if (m_firstX) |
| 870 firstPoint.setX(size.width() - secondPoint.x()); | 873 firstPoint.setX(size.width() - secondPoint.x()); |
| 871 if (m_firstY) | 874 if (m_firstY) |
| 872 firstPoint.setY(size.height() - secondPoint.y()); | 875 firstPoint.setY(size.height() - secondPoint.y()); |
| 873 } else | 876 } else |
| 874 secondPoint.setY(size.height()); | 877 secondPoint.setY(size.height()); |
| 875 break; | 878 break; |
| 876 default: | 879 default: |
| 877 ASSERT_NOT_REACHED(); | 880 NOTREACHED(); |
| 878 } | 881 } |
| 879 } | 882 } |
| 880 | 883 |
| 881 RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint); | 884 RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint); |
| 882 | 885 |
| 883 gradient->setSpreadMethod(m_repeating ? SpreadMethodRepeat : SpreadMethodPad); | 886 gradient->setSpreadMethod(m_repeating ? SpreadMethodRepeat : SpreadMethodPad); |
| 884 gradient->setDrawsInPMColorSpace(true); | 887 gradient->setDrawsInPMColorSpace(true); |
| 885 | 888 |
| 886 // Now add the stops. | 889 // Now add the stops. |
| 887 addStops(gradient.get(), conversionData, object); | 890 addStops(gradient.get(), conversionData, object); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1111 float dy1 = clampTo<float>(fabs(point.y())); | 1114 float dy1 = clampTo<float>(fabs(point.y())); |
| 1112 float dx2 = clampTo<float>(fabs(point.x() - size.width())); | 1115 float dx2 = clampTo<float>(fabs(point.x() - size.width())); |
| 1113 float dy2 = clampTo<float>(fabs(point.y() - size.height())); | 1116 float dy2 = clampTo<float>(fabs(point.y() - size.height())); |
| 1114 | 1117 |
| 1115 float dx = compare(dx1, dx2) ? dx1 : dx2; | 1118 float dx = compare(dx1, dx2) ? dx1 : dx2; |
| 1116 float dy = compare(dy1, dy2) ? dy1 : dy2; | 1119 float dy = compare(dy1, dy2) ? dy1 : dy2; |
| 1117 | 1120 |
| 1118 if (shape == CircleEndShape) | 1121 if (shape == CircleEndShape) |
| 1119 return compare(dx, dy) ? FloatSize(dx, dx) : FloatSize(dy, dy); | 1122 return compare(dx, dy) ? FloatSize(dx, dx) : FloatSize(dy, dy); |
| 1120 | 1123 |
| 1121 ASSERT(shape == EllipseEndShape); | 1124 DCHECK_EQ(shape, EllipseEndShape); |
| 1122 return FloatSize(dx, dy); | 1125 return FloatSize(dx, dy); |
| 1123 } | 1126 } |
| 1124 | 1127 |
| 1125 // Compute the radius of an ellipse with center at 0,0 which passes through p, | 1128 // Compute the radius of an ellipse with center at 0,0 which passes through p, |
| 1126 // and has width/height given by aspectRatio. | 1129 // and has width/height given by aspectRatio. |
| 1127 inline FloatSize ellipseRadius(const FloatPoint& p, float aspectRatio) { | 1130 inline FloatSize ellipseRadius(const FloatPoint& p, float aspectRatio) { |
| 1128 // If the aspectRatio is 0 or infinite, the ellipse is completely flat. | 1131 // If the aspectRatio is 0 or infinite, the ellipse is completely flat. |
| 1129 // TODO(sashab): Implement Degenerate Radial Gradients, see crbug.com/635727. | 1132 // TODO(sashab): Implement Degenerate Radial Gradients, see crbug.com/635727. |
| 1130 if (aspectRatio == 0 || std::isinf(aspectRatio)) | 1133 if (aspectRatio == 0 || std::isinf(aspectRatio)) |
| 1131 return FloatSize(0, 0); | 1134 return FloatSize(0, 0); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1153 float newDistance = (point - corners[i]).diagonalLength(); | 1156 float newDistance = (point - corners[i]).diagonalLength(); |
| 1154 if (compare(newDistance, distance)) { | 1157 if (compare(newDistance, distance)) { |
| 1155 cornerIndex = i; | 1158 cornerIndex = i; |
| 1156 distance = newDistance; | 1159 distance = newDistance; |
| 1157 } | 1160 } |
| 1158 } | 1161 } |
| 1159 | 1162 |
| 1160 if (shape == CircleEndShape) | 1163 if (shape == CircleEndShape) |
| 1161 return FloatSize(distance, distance); | 1164 return FloatSize(distance, distance); |
| 1162 | 1165 |
| 1163 ASSERT(shape == EllipseEndShape); | 1166 DCHECK_EQ(shape, EllipseEndShape); |
| 1164 // If the end shape is an ellipse, the gradient-shape has the same ratio of | 1167 // If the end shape is an ellipse, the gradient-shape has the same ratio of |
| 1165 // width to height that it would if closest-side or farthest-side were | 1168 // width to height that it would if closest-side or farthest-side were |
| 1166 // specified, as appropriate. | 1169 // specified, as appropriate. |
| 1167 const FloatSize sideRadius = | 1170 const FloatSize sideRadius = |
| 1168 radiusToSide(point, size, EllipseEndShape, compare); | 1171 radiusToSide(point, size, EllipseEndShape, compare); |
| 1169 | 1172 |
| 1170 return ellipseRadius(FloatPoint(corners[cornerIndex] - point), | 1173 return ellipseRadius(FloatPoint(corners[cornerIndex] - point), |
| 1171 sideRadius.aspectRatio()); | 1174 sideRadius.aspectRatio()); |
| 1172 } | 1175 } |
| 1173 | 1176 |
| 1174 } // anonymous namespace | 1177 } // anonymous namespace |
| 1175 | 1178 |
| 1176 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient( | 1179 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient( |
| 1177 const CSSToLengthConversionData& conversionData, | 1180 const CSSToLengthConversionData& conversionData, |
| 1178 const IntSize& size, | 1181 const IntSize& size, |
| 1179 const LayoutObject& object) { | 1182 const LayoutObject& object) { |
| 1180 ASSERT(!size.isEmpty()); | 1183 DCHECK(!size.isEmpty()); |
| 1181 | 1184 |
| 1182 FloatPoint firstPoint = | 1185 FloatPoint firstPoint = |
| 1183 computeEndPoint(m_firstX.get(), m_firstY.get(), conversionData, size); | 1186 computeEndPoint(m_firstX.get(), m_firstY.get(), conversionData, size); |
| 1184 if (!m_firstX) | 1187 if (!m_firstX) |
| 1185 firstPoint.setX(size.width() / 2); | 1188 firstPoint.setX(size.width() / 2); |
| 1186 if (!m_firstY) | 1189 if (!m_firstY) |
| 1187 firstPoint.setY(size.height() / 2); | 1190 firstPoint.setY(size.height() / 2); |
| 1188 | 1191 |
| 1189 FloatPoint secondPoint = | 1192 FloatPoint secondPoint = |
| 1190 computeEndPoint(m_secondX.get(), m_secondY.get(), conversionData, size); | 1193 computeEndPoint(m_secondX.get(), m_secondY.get(), conversionData, size); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1314 visitor->trace(m_firstRadius); | 1317 visitor->trace(m_firstRadius); |
| 1315 visitor->trace(m_secondRadius); | 1318 visitor->trace(m_secondRadius); |
| 1316 visitor->trace(m_shape); | 1319 visitor->trace(m_shape); |
| 1317 visitor->trace(m_sizingBehavior); | 1320 visitor->trace(m_sizingBehavior); |
| 1318 visitor->trace(m_endHorizontalSize); | 1321 visitor->trace(m_endHorizontalSize); |
| 1319 visitor->trace(m_endVerticalSize); | 1322 visitor->trace(m_endVerticalSize); |
| 1320 CSSGradientValue::traceAfterDispatch(visitor); | 1323 CSSGradientValue::traceAfterDispatch(visitor); |
| 1321 } | 1324 } |
| 1322 | 1325 |
| 1323 } // namespace blink | 1326 } // namespace blink |
| OLD | NEW |