| 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 10 matching lines...) Expand all Loading... |
| 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "core/css/CSSGradientValue.h" | 27 #include "core/css/CSSGradientValue.h" |
| 28 | 28 |
| 29 #include "core/CSSValueKeywords.h" | 29 #include "core/CSSValueKeywords.h" |
| 30 #include "core/css/CSSCalculationValue.h" | 30 #include "core/css/CSSCalculationValue.h" |
| 31 #include "core/css/CSSIdentifierValue.h" |
| 31 #include "core/css/CSSToLengthConversionData.h" | 32 #include "core/css/CSSToLengthConversionData.h" |
| 32 #include "core/css/CSSValuePair.h" | 33 #include "core/css/CSSValuePair.h" |
| 33 #include "core/dom/NodeComputedStyle.h" | 34 #include "core/dom/NodeComputedStyle.h" |
| 34 #include "core/dom/TextLinkColors.h" | 35 #include "core/dom/TextLinkColors.h" |
| 35 #include "core/layout/LayoutObject.h" | 36 #include "core/layout/LayoutObject.h" |
| 36 #include "core/layout/api/LayoutViewItem.h" | 37 #include "core/layout/api/LayoutViewItem.h" |
| 37 #include "platform/geometry/IntSize.h" | 38 #include "platform/geometry/IntSize.h" |
| 38 #include "platform/graphics/Gradient.h" | 39 #include "platform/graphics/Gradient.h" |
| 39 #include "platform/graphics/GradientGeneratedImage.h" | 40 #include "platform/graphics/GradientGeneratedImage.h" |
| 40 #include "platform/graphics/Image.h" | 41 #include "platform/graphics/Image.h" |
| 41 #include "platform/graphics/skia/SkiaUtils.h" | 42 #include "platform/graphics/skia/SkiaUtils.h" |
| 42 #include "wtf/text/StringBuilder.h" | 43 #include "wtf/text/StringBuilder.h" |
| 43 #include "wtf/text/WTFString.h" | 44 #include "wtf/text/WTFString.h" |
| 44 #include <algorithm> | 45 #include <algorithm> |
| 45 #include <utility> | 46 #include <utility> |
| 46 | 47 |
| 47 namespace blink { | 48 namespace blink { |
| 48 | 49 |
| 50 namespace { |
| 51 |
| 52 static bool colorIsDerivedFromElement(const CSSIdentifierValue& value) { |
| 53 CSSValueID valueID = value.getValueID(); |
| 54 switch (valueID) { |
| 55 case CSSValueInternalQuirkInherit: |
| 56 case CSSValueWebkitLink: |
| 57 case CSSValueWebkitActivelink: |
| 58 case CSSValueCurrentcolor: |
| 59 return true; |
| 60 default: |
| 61 return false; |
| 62 } |
| 63 } |
| 64 } |
| 65 |
| 49 DEFINE_TRACE(CSSGradientColorStop) { | 66 DEFINE_TRACE(CSSGradientColorStop) { |
| 50 visitor->trace(m_position); | 67 visitor->trace(m_position); |
| 51 visitor->trace(m_color); | 68 visitor->trace(m_color); |
| 52 } | 69 } |
| 53 | 70 |
| 54 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, | 71 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, |
| 55 const IntSize& size) { | 72 const IntSize& size) { |
| 56 if (size.isEmpty()) | 73 if (size.isEmpty()) |
| 57 return nullptr; | 74 return nullptr; |
| 58 | 75 |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 const IntSize& size, | 522 const IntSize& size, |
| 506 bool isHorizontal) { | 523 bool isHorizontal) { |
| 507 int origin = 0; | 524 int origin = 0; |
| 508 int sign = 1; | 525 int sign = 1; |
| 509 int edgeDistance = isHorizontal ? size.width() : size.height(); | 526 int edgeDistance = isHorizontal ? size.width() : size.height(); |
| 510 | 527 |
| 511 // In this case the center of the gradient is given relative to an edge in the
form of: | 528 // In this case the center of the gradient is given relative to an edge in the
form of: |
| 512 // [ top | bottom | right | left ] [ <percentage> | <length> ]. | 529 // [ top | bottom | right | left ] [ <percentage> | <length> ]. |
| 513 if (value->isValuePair()) { | 530 if (value->isValuePair()) { |
| 514 const CSSValuePair& pair = toCSSValuePair(*value); | 531 const CSSValuePair& pair = toCSSValuePair(*value); |
| 515 CSSValueID originID = toCSSPrimitiveValue(pair.first()).getValueID(); | 532 CSSValueID originID = toCSSIdentifierValue(pair.first()).getValueID(); |
| 516 value = &pair.second(); | 533 value = &pair.second(); |
| 517 | 534 |
| 518 if (originID == CSSValueRight || originID == CSSValueBottom) { | 535 if (originID == CSSValueRight || originID == CSSValueBottom) { |
| 519 // For right/bottom, the offset is relative to the far edge. | 536 // For right/bottom, the offset is relative to the far edge. |
| 520 origin = edgeDistance; | 537 origin = edgeDistance; |
| 521 sign = -1; | 538 sign = -1; |
| 522 } | 539 } |
| 523 } | 540 } |
| 524 | 541 |
| 542 if (value->isIdentifierValue()) { |
| 543 switch (toCSSIdentifierValue(value)->getValueID()) { |
| 544 case CSSValueTop: |
| 545 DCHECK(!isHorizontal); |
| 546 return 0; |
| 547 case CSSValueLeft: |
| 548 DCHECK(isHorizontal); |
| 549 return 0; |
| 550 case CSSValueBottom: |
| 551 DCHECK(!isHorizontal); |
| 552 return size.height(); |
| 553 case CSSValueRight: |
| 554 DCHECK(isHorizontal); |
| 555 return size.width(); |
| 556 case CSSValueCenter: |
| 557 return origin + sign * .5f * edgeDistance; |
| 558 default: |
| 559 NOTREACHED(); |
| 560 break; |
| 561 } |
| 562 } |
| 563 |
| 525 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); | 564 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| 526 | 565 |
| 527 if (primitiveValue->isNumber()) | 566 if (primitiveValue->isNumber()) |
| 528 return origin + | 567 return origin + |
| 529 sign * primitiveValue->getFloatValue() * conversionData.zoom(); | 568 sign * primitiveValue->getFloatValue() * conversionData.zoom(); |
| 530 | 569 |
| 531 if (primitiveValue->isPercentage()) | 570 if (primitiveValue->isPercentage()) |
| 532 return origin + | 571 return origin + |
| 533 sign * primitiveValue->getFloatValue() / 100.f * edgeDistance; | 572 sign * primitiveValue->getFloatValue() / 100.f * edgeDistance; |
| 534 | 573 |
| 535 if (primitiveValue->isCalculatedPercentageWithLength()) | 574 if (primitiveValue->isCalculatedPercentageWithLength()) |
| 536 return origin + | 575 return origin + |
| 537 sign * | 576 sign * |
| 538 primitiveValue->cssCalcValue() | 577 primitiveValue->cssCalcValue() |
| 539 ->toCalcValue(conversionData) | 578 ->toCalcValue(conversionData) |
| 540 ->evaluate(edgeDistance); | 579 ->evaluate(edgeDistance); |
| 541 | 580 |
| 542 switch (primitiveValue->getValueID()) { | |
| 543 case CSSValueTop: | |
| 544 ASSERT(!isHorizontal); | |
| 545 return 0; | |
| 546 case CSSValueLeft: | |
| 547 ASSERT(isHorizontal); | |
| 548 return 0; | |
| 549 case CSSValueBottom: | |
| 550 ASSERT(!isHorizontal); | |
| 551 return size.height(); | |
| 552 case CSSValueRight: | |
| 553 ASSERT(isHorizontal); | |
| 554 return size.width(); | |
| 555 case CSSValueCenter: | |
| 556 return origin + sign * .5f * edgeDistance; | |
| 557 default: | |
| 558 break; | |
| 559 } | |
| 560 | |
| 561 return origin + sign * primitiveValue->computeLength<float>(conversionData); | 581 return origin + sign * primitiveValue->computeLength<float>(conversionData); |
| 562 } | 582 } |
| 563 | 583 |
| 564 FloatPoint CSSGradientValue::computeEndPoint( | 584 FloatPoint CSSGradientValue::computeEndPoint( |
| 565 CSSValue* horizontal, | 585 CSSValue* horizontal, |
| 566 CSSValue* vertical, | 586 CSSValue* vertical, |
| 567 const CSSToLengthConversionData& conversionData, | 587 const CSSToLengthConversionData& conversionData, |
| 568 const IntSize& size) { | 588 const IntSize& size) { |
| 569 FloatPoint result; | 589 FloatPoint result; |
| 570 | 590 |
| 571 if (horizontal) | 591 if (horizontal) |
| 572 result.setX(positionFromValue(horizontal, conversionData, size, true)); | 592 result.setX(positionFromValue(horizontal, conversionData, size, true)); |
| 573 | 593 |
| 574 if (vertical) | 594 if (vertical) |
| 575 result.setY(positionFromValue(vertical, conversionData, size, false)); | 595 result.setY(positionFromValue(vertical, conversionData, size, false)); |
| 576 | 596 |
| 577 return result; | 597 return result; |
| 578 } | 598 } |
| 579 | 599 |
| 580 bool CSSGradientValue::isCacheable() const { | 600 bool CSSGradientValue::isCacheable() const { |
| 581 for (size_t i = 0; i < m_stops.size(); ++i) { | 601 for (size_t i = 0; i < m_stops.size(); ++i) { |
| 582 const CSSGradientColorStop& stop = m_stops[i]; | 602 const CSSGradientColorStop& stop = m_stops[i]; |
| 583 | 603 |
| 584 if (!stop.isHint() && stop.m_color->isPrimitiveValue() && | 604 if (!stop.isHint() && stop.m_color->isIdentifierValue() && |
| 585 toCSSPrimitiveValue(*stop.m_color).colorIsDerivedFromElement()) | 605 colorIsDerivedFromElement(toCSSIdentifierValue(*stop.m_color))) |
| 586 return false; | 606 return false; |
| 587 | 607 |
| 588 if (!stop.m_position) | 608 if (!stop.m_position) |
| 589 continue; | 609 continue; |
| 590 | 610 |
| 591 if (stop.m_position->isFontRelativeLength()) | 611 if (stop.m_position->isFontRelativeLength()) |
| 592 return false; | 612 return false; |
| 593 } | 613 } |
| 594 | 614 |
| 595 return true; | 615 return true; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 result.append("repeating-linear-gradient("); | 688 result.append("repeating-linear-gradient("); |
| 669 else | 689 else |
| 670 result.append("linear-gradient("); | 690 result.append("linear-gradient("); |
| 671 | 691 |
| 672 bool wroteSomething = false; | 692 bool wroteSomething = false; |
| 673 | 693 |
| 674 if (m_angle && m_angle->computeDegrees() != 180) { | 694 if (m_angle && m_angle->computeDegrees() != 180) { |
| 675 result.append(m_angle->cssText()); | 695 result.append(m_angle->cssText()); |
| 676 wroteSomething = true; | 696 wroteSomething = true; |
| 677 } else if ((m_firstX || m_firstY) && | 697 } else if ((m_firstX || m_firstY) && |
| 678 !(!m_firstX && m_firstY && m_firstY->isPrimitiveValue() && | 698 !(!m_firstX && m_firstY && m_firstY->isIdentifierValue() && |
| 679 toCSSPrimitiveValue(m_firstY.get())->getValueID() == | 699 toCSSIdentifierValue(m_firstY.get())->getValueID() == |
| 680 CSSValueBottom)) { | 700 CSSValueBottom)) { |
| 681 result.append("to "); | 701 result.append("to "); |
| 682 if (m_firstX && m_firstY) { | 702 if (m_firstX && m_firstY) { |
| 683 result.append(m_firstX->cssText()); | 703 result.append(m_firstX->cssText()); |
| 684 result.append(' '); | 704 result.append(' '); |
| 685 result.append(m_firstY->cssText()); | 705 result.append(m_firstY->cssText()); |
| 686 } else if (m_firstX) | 706 } else if (m_firstX) |
| 687 result.append(m_firstX->cssText()); | 707 result.append(m_firstX->cssText()); |
| 688 else | 708 else |
| 689 result.append(m_firstY->cssText()); | 709 result.append(m_firstY->cssText()); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 if (m_firstX) | 833 if (m_firstX) |
| 814 secondPoint.setX(size.width() - firstPoint.x()); | 834 secondPoint.setX(size.width() - firstPoint.x()); |
| 815 if (m_firstY) | 835 if (m_firstY) |
| 816 secondPoint.setY(size.height() - firstPoint.y()); | 836 secondPoint.setY(size.height() - firstPoint.y()); |
| 817 break; | 837 break; |
| 818 case CSSLinearGradient: | 838 case CSSLinearGradient: |
| 819 if (m_firstX && m_firstY) { | 839 if (m_firstX && m_firstY) { |
| 820 // "Magic" corners, so the 50% line touches two corners. | 840 // "Magic" corners, so the 50% line touches two corners. |
| 821 float rise = size.width(); | 841 float rise = size.width(); |
| 822 float run = size.height(); | 842 float run = size.height(); |
| 823 if (m_firstX && m_firstX->isPrimitiveValue() && | 843 if (m_firstX && m_firstX->isIdentifierValue() && |
| 824 toCSSPrimitiveValue(m_firstX.get())->getValueID() == CSSValueLeft) | 844 toCSSIdentifierValue(m_firstX.get())->getValueID() == |
| 845 CSSValueLeft) |
| 825 run *= -1; | 846 run *= -1; |
| 826 if (m_firstY && m_firstY->isPrimitiveValue() && | 847 if (m_firstY && m_firstY->isIdentifierValue() && |
| 827 toCSSPrimitiveValue(m_firstY.get())->getValueID() == | 848 toCSSIdentifierValue(m_firstY.get())->getValueID() == |
| 828 CSSValueBottom) | 849 CSSValueBottom) |
| 829 rise *= -1; | 850 rise *= -1; |
| 830 // Compute angle, and flip it back to "bearing angle" degrees. | 851 // Compute angle, and flip it back to "bearing angle" degrees. |
| 831 float angle = 90 - rad2deg(atan2(rise, run)); | 852 float angle = 90 - rad2deg(atan2(rise, run)); |
| 832 endPointsFromAngle(angle, size, firstPoint, secondPoint, | 853 endPointsFromAngle(angle, size, firstPoint, secondPoint, |
| 833 m_gradientType); | 854 m_gradientType); |
| 834 } else if (m_firstX || m_firstY) { | 855 } else if (m_firstX || m_firstY) { |
| 835 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), | 856 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), |
| 836 conversionData, size); | 857 conversionData, size); |
| 837 if (m_firstX) | 858 if (m_firstX) |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 visitor->trace(m_firstRadius); | 1303 visitor->trace(m_firstRadius); |
| 1283 visitor->trace(m_secondRadius); | 1304 visitor->trace(m_secondRadius); |
| 1284 visitor->trace(m_shape); | 1305 visitor->trace(m_shape); |
| 1285 visitor->trace(m_sizingBehavior); | 1306 visitor->trace(m_sizingBehavior); |
| 1286 visitor->trace(m_endHorizontalSize); | 1307 visitor->trace(m_endHorizontalSize); |
| 1287 visitor->trace(m_endVerticalSize); | 1308 visitor->trace(m_endVerticalSize); |
| 1288 CSSGradientValue::traceAfterDispatch(visitor); | 1309 CSSGradientValue::traceAfterDispatch(visitor); |
| 1289 } | 1310 } |
| 1290 | 1311 |
| 1291 } // namespace blink | 1312 } // namespace blink |
| OLD | NEW |