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 12 matching lines...) Expand all Loading... |
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 "config.h" | 27 #include "config.h" |
28 #include "core/css/CSSGradientValue.h" | 28 #include "core/css/CSSGradientValue.h" |
29 | 29 |
30 #include "core/CSSValueKeywords.h" | 30 #include "core/CSSValueKeywords.h" |
31 #include "core/css/CSSCalculationValue.h" | 31 #include "core/css/CSSCalculationValue.h" |
32 #include "core/css/CSSToLengthConversionData.h" | 32 #include "core/css/CSSToLengthConversionData.h" |
33 #include "core/css/Pair.h" | 33 #include "core/css/CSSValuePair.h" |
34 #include "core/dom/NodeComputedStyle.h" | 34 #include "core/dom/NodeComputedStyle.h" |
35 #include "core/dom/TextLinkColors.h" | 35 #include "core/dom/TextLinkColors.h" |
36 #include "core/layout/LayoutObject.h" | 36 #include "core/layout/LayoutObject.h" |
37 #include "platform/geometry/IntSize.h" | 37 #include "platform/geometry/IntSize.h" |
38 #include "platform/graphics/Gradient.h" | 38 #include "platform/graphics/Gradient.h" |
39 #include "platform/graphics/GradientGeneratedImage.h" | 39 #include "platform/graphics/GradientGeneratedImage.h" |
40 #include "platform/graphics/Image.h" | 40 #include "platform/graphics/Image.h" |
41 #include "platform/graphics/skia/SkiaUtils.h" | 41 #include "platform/graphics/skia/SkiaUtils.h" |
42 #include "wtf/text/StringBuilder.h" | 42 #include "wtf/text/StringBuilder.h" |
43 #include "wtf/text/WTFString.h" | 43 #include "wtf/text/WTFString.h" |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 } else { | 473 } else { |
474 // Normalization failed because the stop set is coincident. | 474 // Normalization failed because the stop set is coincident. |
475 } | 475 } |
476 } else { | 476 } else { |
477 // No normalization required, just add the current stops. | 477 // No normalization required, just add the current stops. |
478 for (const auto& stop : stops) | 478 for (const auto& stop : stops) |
479 gradient->addColorStop(stop.offset, stop.color); | 479 gradient->addColorStop(stop.offset, stop.color); |
480 } | 480 } |
481 } | 481 } |
482 | 482 |
483 static float positionFromValue(CSSPrimitiveValue* value, const CSSToLengthConver
sionData& conversionData, const IntSize& size, bool isHorizontal) | 483 static float positionFromValue(CSSValue* value, const CSSToLengthConversionData&
conversionData, const IntSize& size, bool isHorizontal) |
484 { | 484 { |
485 int origin = 0; | 485 int origin = 0; |
486 int sign = 1; | 486 int sign = 1; |
487 int edgeDistance = isHorizontal ? size.width() : size.height(); | 487 int edgeDistance = isHorizontal ? size.width() : size.height(); |
488 | 488 |
489 // In this case the center of the gradient is given relative to an edge in t
he form of: | 489 // In this case the center of the gradient is given relative to an edge in t
he form of: |
490 // [ top | bottom | right | left ] [ <percentage> | <length> ]. | 490 // [ top | bottom | right | left ] [ <percentage> | <length> ]. |
491 if (Pair* pair = value->getPairValue()) { | 491 if (value->isValuePair()) { |
492 CSSValueID originID = pair->first()->getValueID(); | 492 CSSValuePair* pair = toCSSValuePair(value); |
| 493 CSSValueID originID = toCSSPrimitiveValue(pair->first())->getValueID(); |
493 value = pair->second(); | 494 value = pair->second(); |
494 | 495 |
495 if (originID == CSSValueRight || originID == CSSValueBottom) { | 496 if (originID == CSSValueRight || originID == CSSValueBottom) { |
496 // For right/bottom, the offset is relative to the far edge. | 497 // For right/bottom, the offset is relative to the far edge. |
497 origin = edgeDistance; | 498 origin = edgeDistance; |
498 sign = -1; | 499 sign = -1; |
499 } | 500 } |
500 } | 501 } |
501 | 502 |
502 if (value->isNumber()) | 503 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
503 return origin + sign * value->getFloatValue() * conversionData.zoom(); | |
504 | 504 |
505 if (value->isPercentage()) | 505 if (primitiveValue->isNumber()) |
506 return origin + sign * value->getFloatValue() / 100.f * edgeDistance; | 506 return origin + sign * primitiveValue->getFloatValue() * conversionData.
zoom(); |
507 | 507 |
508 if (value->isCalculatedPercentageWithLength()) | 508 if (primitiveValue->isPercentage()) |
509 return origin + sign * value->cssCalcValue()->toCalcValue(conversionData
)->evaluate(edgeDistance); | 509 return origin + sign * primitiveValue->getFloatValue() / 100.f * edgeDis
tance; |
510 | 510 |
511 switch (value->getValueID()) { | 511 if (primitiveValue->isCalculatedPercentageWithLength()) |
| 512 return origin + sign * primitiveValue->cssCalcValue()->toCalcValue(conve
rsionData)->evaluate(edgeDistance); |
| 513 |
| 514 switch (primitiveValue->getValueID()) { |
512 case CSSValueTop: | 515 case CSSValueTop: |
513 ASSERT(!isHorizontal); | 516 ASSERT(!isHorizontal); |
514 return 0; | 517 return 0; |
515 case CSSValueLeft: | 518 case CSSValueLeft: |
516 ASSERT(isHorizontal); | 519 ASSERT(isHorizontal); |
517 return 0; | 520 return 0; |
518 case CSSValueBottom: | 521 case CSSValueBottom: |
519 ASSERT(!isHorizontal); | 522 ASSERT(!isHorizontal); |
520 return size.height(); | 523 return size.height(); |
521 case CSSValueRight: | 524 case CSSValueRight: |
522 ASSERT(isHorizontal); | 525 ASSERT(isHorizontal); |
523 return size.width(); | 526 return size.width(); |
524 default: | 527 default: |
525 break; | 528 break; |
526 } | 529 } |
527 | 530 |
528 return origin + sign * value->computeLength<float>(conversionData); | 531 return origin + sign * primitiveValue->computeLength<float>(conversionData); |
529 } | 532 } |
530 | 533 |
531 FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSP
rimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const
IntSize& size) | 534 FloatPoint CSSGradientValue::computeEndPoint(CSSValue* horizontal, CSSValue* ver
tical, const CSSToLengthConversionData& conversionData, const IntSize& size) |
532 { | 535 { |
533 FloatPoint result; | 536 FloatPoint result; |
534 | 537 |
535 if (horizontal) | 538 if (horizontal) |
536 result.setX(positionFromValue(horizontal, conversionData, size, true)); | 539 result.setX(positionFromValue(horizontal, conversionData, size, true)); |
537 | 540 |
538 if (vertical) | 541 if (vertical) |
539 result.setY(positionFromValue(vertical, conversionData, size, false)); | 542 result.setY(positionFromValue(vertical, conversionData, size, false)); |
540 | 543 |
541 return result; | 544 return result; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 if (m_repeating) | 632 if (m_repeating) |
630 result.appendLiteral("repeating-linear-gradient("); | 633 result.appendLiteral("repeating-linear-gradient("); |
631 else | 634 else |
632 result.appendLiteral("linear-gradient("); | 635 result.appendLiteral("linear-gradient("); |
633 | 636 |
634 bool wroteSomething = false; | 637 bool wroteSomething = false; |
635 | 638 |
636 if (m_angle && m_angle->computeDegrees() != 180) { | 639 if (m_angle && m_angle->computeDegrees() != 180) { |
637 result.append(m_angle->cssText()); | 640 result.append(m_angle->cssText()); |
638 wroteSomething = true; | 641 wroteSomething = true; |
639 } else if ((m_firstX || m_firstY) && !(!m_firstX && m_firstY && m_firstY
->getValueID() == CSSValueBottom)) { | 642 } else if ((m_firstX || m_firstY) && !(!m_firstX && m_firstY && m_firstY
->isPrimitiveValue() && toCSSPrimitiveValue(m_firstY.get())->getValueID() == CSS
ValueBottom)) { |
640 result.appendLiteral("to "); | 643 result.appendLiteral("to "); |
641 if (m_firstX && m_firstY) { | 644 if (m_firstX && m_firstY) { |
642 result.append(m_firstX->cssText()); | 645 result.append(m_firstX->cssText()); |
643 result.append(' '); | 646 result.append(' '); |
644 result.append(m_firstY->cssText()); | 647 result.append(m_firstY->cssText()); |
645 } else if (m_firstX) | 648 } else if (m_firstX) |
646 result.append(m_firstX->cssText()); | 649 result.append(m_firstX->cssText()); |
647 else | 650 else |
648 result.append(m_firstY->cssText()); | 651 result.append(m_firstY->cssText()); |
649 wroteSomething = true; | 652 wroteSomething = true; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 if (m_firstX) | 768 if (m_firstX) |
766 secondPoint.setX(size.width() - firstPoint.x()); | 769 secondPoint.setX(size.width() - firstPoint.x()); |
767 if (m_firstY) | 770 if (m_firstY) |
768 secondPoint.setY(size.height() - firstPoint.y()); | 771 secondPoint.setY(size.height() - firstPoint.y()); |
769 break; | 772 break; |
770 case CSSLinearGradient: | 773 case CSSLinearGradient: |
771 if (m_firstX && m_firstY) { | 774 if (m_firstX && m_firstY) { |
772 // "Magic" corners, so the 50% line touches two corners. | 775 // "Magic" corners, so the 50% line touches two corners. |
773 float rise = size.width(); | 776 float rise = size.width(); |
774 float run = size.height(); | 777 float run = size.height(); |
775 if (m_firstX && m_firstX->getValueID() == CSSValueLeft) | 778 if (m_firstX && m_firstX->isPrimitiveValue() && toCSSPrimitiveVa
lue(m_firstX.get())->getValueID() == CSSValueLeft) |
776 run *= -1; | 779 run *= -1; |
777 if (m_firstY && m_firstY->getValueID() == CSSValueBottom) | 780 if (m_firstY && m_firstY->isPrimitiveValue() && toCSSPrimitiveVa
lue(m_firstY.get())->getValueID() == CSSValueBottom) |
778 rise *= -1; | 781 rise *= -1; |
779 // Compute angle, and flip it back to "bearing angle" degrees. | 782 // Compute angle, and flip it back to "bearing angle" degrees. |
780 float angle = 90 - rad2deg(atan2(rise, run)); | 783 float angle = 90 - rad2deg(atan2(rise, run)); |
781 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); | 784 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); |
782 } else if (m_firstX || m_firstY) { | 785 } else if (m_firstX || m_firstY) { |
783 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), co
nversionData, size); | 786 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), co
nversionData, size); |
784 if (m_firstX) | 787 if (m_firstX) |
785 firstPoint.setX(size.width() - secondPoint.x()); | 788 firstPoint.setX(size.width() - secondPoint.x()); |
786 if (m_firstY) | 789 if (m_firstY) |
787 firstPoint.setY(size.height() - secondPoint.y()); | 790 firstPoint.setY(size.height() - secondPoint.y()); |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 visitor->trace(m_firstRadius); | 1207 visitor->trace(m_firstRadius); |
1205 visitor->trace(m_secondRadius); | 1208 visitor->trace(m_secondRadius); |
1206 visitor->trace(m_shape); | 1209 visitor->trace(m_shape); |
1207 visitor->trace(m_sizingBehavior); | 1210 visitor->trace(m_sizingBehavior); |
1208 visitor->trace(m_endHorizontalSize); | 1211 visitor->trace(m_endHorizontalSize); |
1209 visitor->trace(m_endVerticalSize); | 1212 visitor->trace(m_endVerticalSize); |
1210 CSSGradientValue::traceAfterDispatch(visitor); | 1213 CSSGradientValue::traceAfterDispatch(visitor); |
1211 } | 1214 } |
1212 | 1215 |
1213 } // namespace blink | 1216 } // namespace blink |
OLD | NEW |