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 { |
| 54 CSSValueID valueID = value.getValueID(); |
| 55 switch (valueID) { |
| 56 case CSSValueInternalQuirkInherit: |
| 57 case CSSValueWebkitLink: |
| 58 case CSSValueWebkitActivelink: |
| 59 case CSSValueCurrentcolor: |
| 60 return true; |
| 61 default: |
| 62 return false; |
| 63 } |
| 64 } |
| 65 |
| 66 } |
| 67 |
49 DEFINE_TRACE(CSSGradientColorStop) | 68 DEFINE_TRACE(CSSGradientColorStop) |
50 { | 69 { |
51 visitor->trace(m_position); | 70 visitor->trace(m_position); |
52 visitor->trace(m_color); | 71 visitor->trace(m_color); |
53 } | 72 } |
54 | 73 |
55 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, cons
t IntSize& size) | 74 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, cons
t IntSize& size) |
56 { | 75 { |
57 if (size.isEmpty()) | 76 if (size.isEmpty()) |
58 return nullptr; | 77 return nullptr; |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 static float positionFromValue(const CSSValue* value, const CSSToLengthConversio
nData& conversionData, const IntSize& size, bool isHorizontal) | 503 static float positionFromValue(const CSSValue* value, const CSSToLengthConversio
nData& conversionData, const IntSize& size, bool isHorizontal) |
485 { | 504 { |
486 int origin = 0; | 505 int origin = 0; |
487 int sign = 1; | 506 int sign = 1; |
488 int edgeDistance = isHorizontal ? size.width() : size.height(); | 507 int edgeDistance = isHorizontal ? size.width() : size.height(); |
489 | 508 |
490 // In this case the center of the gradient is given relative to an edge in t
he form of: | 509 // In this case the center of the gradient is given relative to an edge in t
he form of: |
491 // [ top | bottom | right | left ] [ <percentage> | <length> ]. | 510 // [ top | bottom | right | left ] [ <percentage> | <length> ]. |
492 if (value->isValuePair()) { | 511 if (value->isValuePair()) { |
493 const CSSValuePair& pair = toCSSValuePair(*value); | 512 const CSSValuePair& pair = toCSSValuePair(*value); |
494 CSSValueID originID = toCSSPrimitiveValue(pair.first()).getValueID(); | 513 CSSValueID originID = toCSSIdentifierValue(pair.first()).getValueID(); |
495 value = &pair.second(); | 514 value = &pair.second(); |
496 | 515 |
497 if (originID == CSSValueRight || originID == CSSValueBottom) { | 516 if (originID == CSSValueRight || originID == CSSValueBottom) { |
498 // For right/bottom, the offset is relative to the far edge. | 517 // For right/bottom, the offset is relative to the far edge. |
499 origin = edgeDistance; | 518 origin = edgeDistance; |
500 sign = -1; | 519 sign = -1; |
501 } | 520 } |
502 } | 521 } |
503 | 522 |
| 523 if (value->isIdentifierValue()) { |
| 524 switch (toCSSIdentifierValue(value)->getValueID()) { |
| 525 case CSSValueTop: |
| 526 DCHECK(!isHorizontal); |
| 527 return 0; |
| 528 case CSSValueLeft: |
| 529 DCHECK(isHorizontal); |
| 530 return 0; |
| 531 case CSSValueBottom: |
| 532 DCHECK(!isHorizontal); |
| 533 return size.height(); |
| 534 case CSSValueRight: |
| 535 DCHECK(isHorizontal); |
| 536 return size.width(); |
| 537 case CSSValueCenter: |
| 538 return origin + sign * .5f * edgeDistance; |
| 539 default: |
| 540 NOTREACHED(); |
| 541 break; |
| 542 } |
| 543 } |
| 544 |
504 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); | 545 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
505 | 546 |
506 if (primitiveValue->isNumber()) | 547 if (primitiveValue->isNumber()) |
507 return origin + sign * primitiveValue->getFloatValue() * conversionData.
zoom(); | 548 return origin + sign * primitiveValue->getFloatValue() * conversionData.
zoom(); |
508 | 549 |
509 if (primitiveValue->isPercentage()) | 550 if (primitiveValue->isPercentage()) |
510 return origin + sign * primitiveValue->getFloatValue() / 100.f * edgeDis
tance; | 551 return origin + sign * primitiveValue->getFloatValue() / 100.f * edgeDis
tance; |
511 | 552 |
512 if (primitiveValue->isCalculatedPercentageWithLength()) | 553 if (primitiveValue->isCalculatedPercentageWithLength()) |
513 return origin + sign * primitiveValue->cssCalcValue()->toCalcValue(conve
rsionData)->evaluate(edgeDistance); | 554 return origin + sign * primitiveValue->cssCalcValue()->toCalcValue(conve
rsionData)->evaluate(edgeDistance); |
514 | 555 |
515 switch (primitiveValue->getValueID()) { | |
516 case CSSValueTop: | |
517 ASSERT(!isHorizontal); | |
518 return 0; | |
519 case CSSValueLeft: | |
520 ASSERT(isHorizontal); | |
521 return 0; | |
522 case CSSValueBottom: | |
523 ASSERT(!isHorizontal); | |
524 return size.height(); | |
525 case CSSValueRight: | |
526 ASSERT(isHorizontal); | |
527 return size.width(); | |
528 case CSSValueCenter: | |
529 return origin + sign * .5f * edgeDistance; | |
530 default: | |
531 break; | |
532 } | |
533 | |
534 return origin + sign * primitiveValue->computeLength<float>(conversionData); | 556 return origin + sign * primitiveValue->computeLength<float>(conversionData); |
535 } | 557 } |
536 | 558 |
537 FloatPoint CSSGradientValue::computeEndPoint(CSSValue* horizontal, CSSValue* ver
tical, const CSSToLengthConversionData& conversionData, const IntSize& size) | 559 FloatPoint CSSGradientValue::computeEndPoint(CSSValue* horizontal, CSSValue* ver
tical, const CSSToLengthConversionData& conversionData, const IntSize& size) |
538 { | 560 { |
539 FloatPoint result; | 561 FloatPoint result; |
540 | 562 |
541 if (horizontal) | 563 if (horizontal) |
542 result.setX(positionFromValue(horizontal, conversionData, size, true)); | 564 result.setX(positionFromValue(horizontal, conversionData, size, true)); |
543 | 565 |
544 if (vertical) | 566 if (vertical) |
545 result.setY(positionFromValue(vertical, conversionData, size, false)); | 567 result.setY(positionFromValue(vertical, conversionData, size, false)); |
546 | 568 |
547 return result; | 569 return result; |
548 } | 570 } |
549 | 571 |
550 bool CSSGradientValue::isCacheable() const | 572 bool CSSGradientValue::isCacheable() const |
551 { | 573 { |
552 for (size_t i = 0; i < m_stops.size(); ++i) { | 574 for (size_t i = 0; i < m_stops.size(); ++i) { |
553 const CSSGradientColorStop& stop = m_stops[i]; | 575 const CSSGradientColorStop& stop = m_stops[i]; |
554 | 576 |
555 if (!stop.isHint() && stop.m_color->isPrimitiveValue() && toCSSPrimitive
Value(*stop.m_color).colorIsDerivedFromElement()) | 577 if (!stop.isHint() && stop.m_color->isIdentifierValue() && colorIsDerive
dFromElement(toCSSIdentifierValue(*stop.m_color))) |
556 return false; | 578 return false; |
557 | 579 |
558 if (!stop.m_position) | 580 if (!stop.m_position) |
559 continue; | 581 continue; |
560 | 582 |
561 if (stop.m_position->isFontRelativeLength()) | 583 if (stop.m_position->isFontRelativeLength()) |
562 return false; | 584 return false; |
563 } | 585 } |
564 | 586 |
565 return true; | 587 return true; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 if (m_repeating) | 663 if (m_repeating) |
642 result.append("repeating-linear-gradient("); | 664 result.append("repeating-linear-gradient("); |
643 else | 665 else |
644 result.append("linear-gradient("); | 666 result.append("linear-gradient("); |
645 | 667 |
646 bool wroteSomething = false; | 668 bool wroteSomething = false; |
647 | 669 |
648 if (m_angle && m_angle->computeDegrees() != 180) { | 670 if (m_angle && m_angle->computeDegrees() != 180) { |
649 result.append(m_angle->cssText()); | 671 result.append(m_angle->cssText()); |
650 wroteSomething = true; | 672 wroteSomething = true; |
651 } else if ((m_firstX || m_firstY) && !(!m_firstX && m_firstY && m_firstY
->isPrimitiveValue() && toCSSPrimitiveValue(m_firstY.get())->getValueID() == CSS
ValueBottom)) { | 673 } else if ((m_firstX || m_firstY) && !(!m_firstX && m_firstY && m_firstY
->isIdentifierValue() && toCSSIdentifierValue(m_firstY.get())->getValueID() == C
SSValueBottom)) { |
652 result.append("to "); | 674 result.append("to "); |
653 if (m_firstX && m_firstY) { | 675 if (m_firstX && m_firstY) { |
654 result.append(m_firstX->cssText()); | 676 result.append(m_firstX->cssText()); |
655 result.append(' '); | 677 result.append(' '); |
656 result.append(m_firstY->cssText()); | 678 result.append(m_firstY->cssText()); |
657 } else if (m_firstX) | 679 } else if (m_firstX) |
658 result.append(m_firstX->cssText()); | 680 result.append(m_firstX->cssText()); |
659 else | 681 else |
660 result.append(m_firstY->cssText()); | 682 result.append(m_firstY->cssText()); |
661 wroteSomething = true; | 683 wroteSomething = true; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 if (m_firstX) | 799 if (m_firstX) |
778 secondPoint.setX(size.width() - firstPoint.x()); | 800 secondPoint.setX(size.width() - firstPoint.x()); |
779 if (m_firstY) | 801 if (m_firstY) |
780 secondPoint.setY(size.height() - firstPoint.y()); | 802 secondPoint.setY(size.height() - firstPoint.y()); |
781 break; | 803 break; |
782 case CSSLinearGradient: | 804 case CSSLinearGradient: |
783 if (m_firstX && m_firstY) { | 805 if (m_firstX && m_firstY) { |
784 // "Magic" corners, so the 50% line touches two corners. | 806 // "Magic" corners, so the 50% line touches two corners. |
785 float rise = size.width(); | 807 float rise = size.width(); |
786 float run = size.height(); | 808 float run = size.height(); |
787 if (m_firstX && m_firstX->isPrimitiveValue() && toCSSPrimitiveVa
lue(m_firstX.get())->getValueID() == CSSValueLeft) | 809 if (m_firstX && m_firstX->isIdentifierValue() && toCSSIdentifier
Value(m_firstX.get())->getValueID() == CSSValueLeft) |
788 run *= -1; | 810 run *= -1; |
789 if (m_firstY && m_firstY->isPrimitiveValue() && toCSSPrimitiveVa
lue(m_firstY.get())->getValueID() == CSSValueBottom) | 811 if (m_firstY && m_firstY->isIdentifierValue() && toCSSIdentifier
Value(m_firstY.get())->getValueID() == CSSValueBottom) |
790 rise *= -1; | 812 rise *= -1; |
791 // Compute angle, and flip it back to "bearing angle" degrees. | 813 // Compute angle, and flip it back to "bearing angle" degrees. |
792 float angle = 90 - rad2deg(atan2(rise, run)); | 814 float angle = 90 - rad2deg(atan2(rise, run)); |
793 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); | 815 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); |
794 } else if (m_firstX || m_firstY) { | 816 } else if (m_firstX || m_firstY) { |
795 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), co
nversionData, size); | 817 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), co
nversionData, size); |
796 if (m_firstX) | 818 if (m_firstX) |
797 firstPoint.setX(size.width() - secondPoint.x()); | 819 firstPoint.setX(size.width() - secondPoint.x()); |
798 if (m_firstY) | 820 if (m_firstY) |
799 firstPoint.setY(size.height() - secondPoint.y()); | 821 firstPoint.setY(size.height() - secondPoint.y()); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 visitor->trace(m_firstRadius); | 1249 visitor->trace(m_firstRadius); |
1228 visitor->trace(m_secondRadius); | 1250 visitor->trace(m_secondRadius); |
1229 visitor->trace(m_shape); | 1251 visitor->trace(m_shape); |
1230 visitor->trace(m_sizingBehavior); | 1252 visitor->trace(m_sizingBehavior); |
1231 visitor->trace(m_endHorizontalSize); | 1253 visitor->trace(m_endHorizontalSize); |
1232 visitor->trace(m_endVerticalSize); | 1254 visitor->trace(m_endVerticalSize); |
1233 CSSGradientValue::traceAfterDispatch(visitor); | 1255 CSSGradientValue::traceAfterDispatch(visitor); |
1234 } | 1256 } |
1235 | 1257 |
1236 } // namespace blink | 1258 } // namespace blink |
OLD | NEW |