| 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 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 if (m_gradientType == CSSDeprecatedLinearGradient || | 451 if (m_gradientType == CSSDeprecatedLinearGradient || |
| 452 m_gradientType == CSSDeprecatedRadialGradient) { | 452 m_gradientType == CSSDeprecatedRadialGradient) { |
| 453 addDeprecatedStops(desc, object); | 453 addDeprecatedStops(desc, object); |
| 454 return; | 454 return; |
| 455 } | 455 } |
| 456 | 456 |
| 457 size_t numStops = m_stops.size(); | 457 size_t numStops = m_stops.size(); |
| 458 | 458 |
| 459 Vector<GradientStop> stops(numStops); | 459 Vector<GradientStop> stops(numStops); |
| 460 | 460 |
| 461 float gradientLength; |
| 462 switch (getClassType()) { |
| 463 case LinearGradientClass: |
| 464 gradientLength = FloatSize(desc.p1 - desc.p0).diagonalLength(); |
| 465 break; |
| 466 case RadialGradientClass: |
| 467 gradientLength = desc.r1; |
| 468 break; |
| 469 case ConicGradientClass: |
| 470 gradientLength = 1; |
| 471 break; |
| 472 default: |
| 473 NOTREACHED(); |
| 474 gradientLength = 0; |
| 475 } |
| 476 |
| 461 bool hasHints = false; | 477 bool hasHints = false; |
| 462 | |
| 463 FloatPoint gradientStart = desc.p0; | |
| 464 FloatPoint gradientEnd; | |
| 465 if (isLinearGradientValue()) | |
| 466 gradientEnd = desc.p1; | |
| 467 else if (isRadialGradientValue()) | |
| 468 gradientEnd = gradientStart + FloatSize(desc.r1, 0); | |
| 469 float gradientLength = | |
| 470 FloatSize(gradientStart - gradientEnd).diagonalLength(); | |
| 471 | |
| 472 for (size_t i = 0; i < numStops; ++i) { | 478 for (size_t i = 0; i < numStops; ++i) { |
| 473 const CSSGradientColorStop& stop = m_stops[i]; | 479 const CSSGradientColorStop& stop = m_stops[i]; |
| 474 | 480 |
| 475 if (stop.isHint()) | 481 if (stop.isHint()) |
| 476 hasHints = true; | 482 hasHints = true; |
| 477 else | 483 else |
| 478 stops[i].color = resolveStopColor(*stop.m_color, object); | 484 stops[i].color = resolveStopColor(*stop.m_color, object); |
| 479 | 485 |
| 480 if (stop.m_offset) { | 486 if (stop.m_offset) { |
| 481 if (stop.m_offset->isPercentage()) { | 487 if (stop.m_offset->isPercentage()) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 565 } |
| 560 } | 566 } |
| 561 | 567 |
| 562 ASSERT(stops.size() == m_stops.size()); | 568 ASSERT(stops.size() == m_stops.size()); |
| 563 if (hasHints) { | 569 if (hasHints) { |
| 564 replaceColorHintsWithColorStops(stops, m_stops); | 570 replaceColorHintsWithColorStops(stops, m_stops); |
| 565 } | 571 } |
| 566 | 572 |
| 567 // At this point we have a fully resolved set of stops. Time to perform | 573 // At this point we have a fully resolved set of stops. Time to perform |
| 568 // adjustments for repeat gradients and degenerate values if needed. | 574 // adjustments for repeat gradients and degenerate values if needed. |
| 569 if (requiresStopsNormalization(stops, desc)) { | 575 // Note: the normalization trick doesn't work for conic gradients, because |
| 570 // Negative offsets are only an issue for non-repeating radial gradients: | 576 // the underlying Skia implementation doesn't support tiling. |
| 571 // linear gradient points can be repositioned arbitrarily, and for repeating | 577 if (isConicGradientValue() || !requiresStopsNormalization(stops, desc)) { |
| 572 // radial gradients we shift the radii into equivalent positive values. | 578 // No normalization required, just add the current stops. |
| 573 if (isRadialGradientValue() && !m_repeating) | 579 for (const auto& stop : stops) |
| 574 clampNegativeOffsets(stops); | 580 desc.stops.emplace_back(stop.offset, stop.color); |
| 581 return; |
| 582 } |
| 575 | 583 |
| 576 if (normalizeAndAddStops(stops, desc)) { | 584 switch (getClassType()) { |
| 577 if (isLinearGradientValue()) { | 585 case LinearGradientClass: |
| 586 if (normalizeAndAddStops(stops, desc)) { |
| 578 adjustGradientPointsForOffsetRange(desc, stops.front().offset, | 587 adjustGradientPointsForOffsetRange(desc, stops.front().offset, |
| 579 stops.back().offset); | 588 stops.back().offset); |
| 580 } else { | 589 } |
| 590 break; |
| 591 case RadialGradientClass: |
| 592 // Negative offsets are only an issue for non-repeating radial gradients: |
| 593 // linear gradient points can be repositioned arbitrarily, and for |
| 594 // repeating radial gradients we shift the radii into equivalent positive |
| 595 // values. |
| 596 if (!m_repeating) |
| 597 clampNegativeOffsets(stops); |
| 598 |
| 599 if (normalizeAndAddStops(stops, desc)) { |
| 581 adjustGradientRadiiForOffsetRange(desc, stops.front().offset, | 600 adjustGradientRadiiForOffsetRange(desc, stops.front().offset, |
| 582 stops.back().offset); | 601 stops.back().offset); |
| 583 } | 602 } |
| 584 } else { | 603 break; |
| 585 // Normalization failed because the stop set is coincident. | 604 default: |
| 586 } | 605 NOTREACHED(); |
| 587 } else { | |
| 588 // No normalization required, just add the current stops. | |
| 589 for (const auto& stop : stops) | |
| 590 desc.stops.emplace_back(stop.offset, stop.color); | |
| 591 } | 606 } |
| 592 } | 607 } |
| 593 | 608 |
| 594 static float positionFromValue(const CSSValue* value, | 609 static float positionFromValue(const CSSValue* value, |
| 595 const CSSToLengthConversionData& conversionData, | 610 const CSSToLengthConversionData& conversionData, |
| 596 const IntSize& size, | 611 const IntSize& size, |
| 597 bool isHorizontal) { | 612 bool isHorizontal) { |
| 598 int origin = 0; | 613 int origin = 0; |
| 599 int sign = 1; | 614 int sign = 1; |
| 600 int edgeDistance = isHorizontal ? size.width() : size.height(); | 615 int edgeDistance = isHorizontal ? size.width() : size.height(); |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 result.append(')'); | 1376 result.append(')'); |
| 1362 return result.toString(); | 1377 return result.toString(); |
| 1363 } | 1378 } |
| 1364 | 1379 |
| 1365 PassRefPtr<Gradient> CSSConicGradientValue::createGradient( | 1380 PassRefPtr<Gradient> CSSConicGradientValue::createGradient( |
| 1366 const CSSToLengthConversionData& conversionData, | 1381 const CSSToLengthConversionData& conversionData, |
| 1367 const IntSize& size, | 1382 const IntSize& size, |
| 1368 const LayoutObject& object) { | 1383 const LayoutObject& object) { |
| 1369 DCHECK(!size.isEmpty()); | 1384 DCHECK(!size.isEmpty()); |
| 1370 | 1385 |
| 1371 // TODO(fmalita): implement | 1386 const float angle = m_fromAngle ? m_fromAngle->computeDegrees() : 0; |
| 1372 return Gradient::createLinear(FloatPoint(), FloatPoint()); | 1387 |
| 1388 const FloatPoint position( |
| 1389 m_firstX ? positionFromValue(m_firstX, conversionData, size, true) |
| 1390 : size.width() / 2, |
| 1391 m_firstY ? positionFromValue(m_firstY, conversionData, size, false) |
| 1392 : size.height() / 2); |
| 1393 |
| 1394 GradientDesc desc(position, position, |
| 1395 m_repeating ? SpreadMethodRepeat : SpreadMethodPad); |
| 1396 addStops(desc, conversionData, object); |
| 1397 |
| 1398 RefPtr<Gradient> gradient = |
| 1399 Gradient::createConic(position, angle, desc.spreadMethod, |
| 1400 Gradient::ColorInterpolation::Premultiplied); |
| 1401 gradient->addColorStops(desc.stops); |
| 1402 |
| 1403 return gradient.release(); |
| 1373 } | 1404 } |
| 1374 | 1405 |
| 1375 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const { | 1406 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const { |
| 1376 return m_repeating == other.m_repeating && | 1407 return m_repeating == other.m_repeating && |
| 1377 dataEquivalent(m_firstX, other.m_firstX) && | 1408 dataEquivalent(m_firstX, other.m_firstX) && |
| 1378 dataEquivalent(m_firstY, other.m_firstY) && | 1409 dataEquivalent(m_firstY, other.m_firstY) && |
| 1379 dataEquivalent(m_fromAngle, other.m_fromAngle) && | 1410 dataEquivalent(m_fromAngle, other.m_fromAngle) && |
| 1380 m_stops == other.m_stops; | 1411 m_stops == other.m_stops; |
| 1381 } | 1412 } |
| 1382 | 1413 |
| 1383 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { | 1414 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { |
| 1384 visitor->trace(m_fromAngle); | 1415 visitor->trace(m_fromAngle); |
| 1385 CSSGradientValue::traceAfterDispatch(visitor); | 1416 CSSGradientValue::traceAfterDispatch(visitor); |
| 1386 } | 1417 } |
| 1387 | 1418 |
| 1388 } // namespace blink | 1419 } // namespace blink |
| OLD | NEW |