| 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 |