| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/css/CSSGradientValue.h" | 27 #include "core/css/CSSGradientValue.h" |
| 28 | 28 |
| 29 #include "CSSValueKeywords.h" | 29 #include "CSSValueKeywords.h" |
| 30 #include "core/css/CSSCalculationValue.h" | 30 #include "core/css/CSSCalculationValue.h" |
| 31 #include "core/css/CSSToLengthConversionData.h" |
| 31 #include "core/dom/NodeRenderStyle.h" | 32 #include "core/dom/NodeRenderStyle.h" |
| 32 #include "core/dom/TextLinkColors.h" | 33 #include "core/dom/TextLinkColors.h" |
| 33 #include "core/platform/graphics/Gradient.h" | 34 #include "core/platform/graphics/Gradient.h" |
| 34 #include "core/platform/graphics/GradientGeneratedImage.h" | 35 #include "core/platform/graphics/GradientGeneratedImage.h" |
| 35 #include "core/platform/graphics/Image.h" | 36 #include "core/platform/graphics/Image.h" |
| 36 #include "core/rendering/RenderObject.h" | 37 #include "core/rendering/RenderObject.h" |
| 37 #include "platform/geometry/IntSize.h" | 38 #include "platform/geometry/IntSize.h" |
| 38 #include "wtf/text/StringBuilder.h" | 39 #include "wtf/text/StringBuilder.h" |
| 39 #include "wtf/text/WTFString.h" | 40 #include "wtf/text/WTFString.h" |
| 40 | 41 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 54 | 55 |
| 55 // Need to look up our size. Create a string of width*height to use as
a hash key. | 56 // Need to look up our size. Create a string of width*height to use as
a hash key. |
| 56 Image* result = getImage(renderer, size); | 57 Image* result = getImage(renderer, size); |
| 57 if (result) | 58 if (result) |
| 58 return result; | 59 return result; |
| 59 } | 60 } |
| 60 | 61 |
| 61 // We need to create an image. | 62 // We need to create an image. |
| 62 RefPtr<Gradient> gradient; | 63 RefPtr<Gradient> gradient; |
| 63 | 64 |
| 65 RenderStyle* rootStyle = renderer->document().documentElement()->renderStyle
(); |
| 66 CSSToLengthConversionData conversionData(renderer->style(), rootStyle); |
| 64 if (isLinearGradientValue()) | 67 if (isLinearGradientValue()) |
| 65 gradient = toCSSLinearGradientValue(this)->createGradient(renderer, size
); | 68 gradient = toCSSLinearGradientValue(this)->createGradient(conversionData
, size); |
| 66 else | 69 else |
| 67 gradient = toCSSRadialGradientValue(this)->createGradient(renderer, size
); | 70 gradient = toCSSRadialGradientValue(this)->createGradient(conversionData
, size); |
| 68 | 71 |
| 69 RefPtr<Image> newImage = GradientGeneratedImage::create(gradient, size); | 72 RefPtr<Image> newImage = GradientGeneratedImage::create(gradient, size); |
| 70 if (cacheable) | 73 if (cacheable) |
| 71 putImage(size, newImage); | 74 putImage(size, newImage); |
| 72 | 75 |
| 73 return newImage.release(); | 76 return newImage.release(); |
| 74 } | 77 } |
| 75 | 78 |
| 76 // Should only ever be called for deprecated gradients. | 79 // Should only ever be called for deprecated gradients. |
| 77 static inline bool compareStops(const CSSGradientColorStop& a, const CSSGradient
ColorStop& b) | 80 static inline bool compareStops(const CSSGradientColorStop& a, const CSSGradient
ColorStop& b) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 ASSERT_NOT_REACHED(); | 127 ASSERT_NOT_REACHED(); |
| 125 return 0; | 128 return 0; |
| 126 } | 129 } |
| 127 | 130 |
| 128 for (unsigned i = 0; i < result->m_stops.size(); i++) | 131 for (unsigned i = 0; i < result->m_stops.size(); i++) |
| 129 result->m_stops[i].m_resolvedColor = textLinkColors.colorFromPrimitiveVa
lue(result->m_stops[i].m_color.get(), currentColor); | 132 result->m_stops[i].m_resolvedColor = textLinkColors.colorFromPrimitiveVa
lue(result->m_stops[i].m_color.get(), currentColor); |
| 130 | 133 |
| 131 return result.release(); | 134 return result.release(); |
| 132 } | 135 } |
| 133 | 136 |
| 134 void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
erStyle* rootStyle, float maxLengthForRepeat) | 137 void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
ata& conversionData, float maxLengthForRepeat) |
| 135 { | 138 { |
| 136 RenderStyle* style = renderer->style(); | |
| 137 | |
| 138 if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDe
precatedRadialGradient) { | 139 if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDe
precatedRadialGradient) { |
| 139 sortStopsIfNeeded(); | 140 sortStopsIfNeeded(); |
| 140 | 141 |
| 141 for (unsigned i = 0; i < m_stops.size(); i++) { | 142 for (unsigned i = 0; i < m_stops.size(); i++) { |
| 142 const CSSGradientColorStop& stop = m_stops[i]; | 143 const CSSGradientColorStop& stop = m_stops[i]; |
| 143 | 144 |
| 144 float offset; | 145 float offset; |
| 145 if (stop.m_position->isPercentage()) | 146 if (stop.m_position->isPercentage()) |
| 146 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_P
ERCENTAGE) / 100; | 147 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_P
ERCENTAGE) / 100; |
| 147 else | 148 else |
| (...skipping 29 matching lines...) Expand all Loading... |
| 177 if (stop.m_position) { | 178 if (stop.m_position) { |
| 178 if (stop.m_position->isPercentage()) | 179 if (stop.m_position->isPercentage()) |
| 179 stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveVal
ue::CSS_PERCENTAGE) / 100; | 180 stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveVal
ue::CSS_PERCENTAGE) / 100; |
| 180 else if (stop.m_position->isLength() || stop.m_position->isCalculate
dPercentageWithLength()) { | 181 else if (stop.m_position->isLength() || stop.m_position->isCalculate
dPercentageWithLength()) { |
| 181 if (!computedGradientLength) { | 182 if (!computedGradientLength) { |
| 182 FloatSize gradientSize(gradientStart - gradientEnd); | 183 FloatSize gradientSize(gradientStart - gradientEnd); |
| 183 gradientLength = gradientSize.diagonalLength(); | 184 gradientLength = gradientSize.diagonalLength(); |
| 184 } | 185 } |
| 185 float length; | 186 float length; |
| 186 if (stop.m_position->isLength()) | 187 if (stop.m_position->isLength()) |
| 187 length = stop.m_position->computeLength<float>(style, rootSt
yle, style->effectiveZoom()); | 188 length = stop.m_position->computeLength<float>(conversionDat
a); |
| 188 else | 189 else |
| 189 length = stop.m_position->cssCalcValue()->toCalcValue(style,
rootStyle, style->effectiveZoom())->evaluate(gradientLength); | 190 length = stop.m_position->cssCalcValue()->toCalcValue(conver
sionData)->evaluate(gradientLength); |
| 190 stops[i].offset = (gradientLength > 0) ? length / gradientLength
: 0; | 191 stops[i].offset = (gradientLength > 0) ? length / gradientLength
: 0; |
| 191 } else { | 192 } else { |
| 192 ASSERT_NOT_REACHED(); | 193 ASSERT_NOT_REACHED(); |
| 193 stops[i].offset = 0; | 194 stops[i].offset = 0; |
| 194 } | 195 } |
| 195 stops[i].specified = true; | 196 stops[i].specified = true; |
| 196 } else { | 197 } else { |
| 197 // If the first color-stop does not have a position, its position de
faults to 0%. | 198 // If the first color-stop does not have a position, its position de
faults to 0%. |
| 198 // If the last color-stop does not have a position, its position def
aults to 100%. | 199 // If the last color-stop does not have a position, its position def
aults to 100%. |
| 199 if (!i) { | 200 if (!i) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 gradient->setEndRadius(gradient->endRadius() * scale); | 381 gradient->setEndRadius(gradient->endRadius() * scale); |
| 381 } | 382 } |
| 382 } | 383 } |
| 383 | 384 |
| 384 for (unsigned i = 0; i < numStops; i++) | 385 for (unsigned i = 0; i < numStops; i++) |
| 385 gradient->addColorStop(stops[i].offset, stops[i].color); | 386 gradient->addColorStop(stops[i].offset, stops[i].color); |
| 386 | 387 |
| 387 gradient->setStopsSorted(true); | 388 gradient->setStopsSorted(true); |
| 388 } | 389 } |
| 389 | 390 |
| 390 static float positionFromValue(CSSPrimitiveValue* value, RenderStyle* style, Ren
derStyle* rootStyle, const IntSize& size, bool isHorizontal) | 391 static float positionFromValue(CSSPrimitiveValue* value, const CSSToLengthConver
sionData& conversionData, const IntSize& size, bool isHorizontal) |
| 391 { | 392 { |
| 392 float zoomFactor = style->effectiveZoom(); | |
| 393 | |
| 394 if (value->isNumber()) | 393 if (value->isNumber()) |
| 395 return value->getFloatValue() * zoomFactor; | 394 return value->getFloatValue() * conversionData.zoom(); |
| 396 | 395 |
| 397 int edgeDistance = isHorizontal ? size.width() : size.height(); | 396 int edgeDistance = isHorizontal ? size.width() : size.height(); |
| 398 if (value->isPercentage()) | 397 if (value->isPercentage()) |
| 399 return value->getFloatValue() / 100.f * edgeDistance; | 398 return value->getFloatValue() / 100.f * edgeDistance; |
| 400 | 399 |
| 401 if (value->isCalculatedPercentageWithLength()) | 400 if (value->isCalculatedPercentageWithLength()) |
| 402 return value->cssCalcValue()->toCalcValue(style, rootStyle, style->effec
tiveZoom())->evaluate(edgeDistance); | 401 return value->cssCalcValue()->toCalcValue(conversionData)->evaluate(edge
Distance); |
| 403 | 402 |
| 404 switch (value->getValueID()) { | 403 switch (value->getValueID()) { |
| 405 case CSSValueTop: | 404 case CSSValueTop: |
| 406 ASSERT(!isHorizontal); | 405 ASSERT(!isHorizontal); |
| 407 return 0; | 406 return 0; |
| 408 case CSSValueLeft: | 407 case CSSValueLeft: |
| 409 ASSERT(isHorizontal); | 408 ASSERT(isHorizontal); |
| 410 return 0; | 409 return 0; |
| 411 case CSSValueBottom: | 410 case CSSValueBottom: |
| 412 ASSERT(!isHorizontal); | 411 ASSERT(!isHorizontal); |
| 413 return size.height(); | 412 return size.height(); |
| 414 case CSSValueRight: | 413 case CSSValueRight: |
| 415 ASSERT(isHorizontal); | 414 ASSERT(isHorizontal); |
| 416 return size.width(); | 415 return size.width(); |
| 417 default: | 416 default: |
| 418 break; | 417 break; |
| 419 } | 418 } |
| 420 | 419 |
| 421 return value->computeLength<float>(style, rootStyle, zoomFactor); | 420 return value->computeLength<float>(conversionData); |
| 422 } | 421 } |
| 423 | 422 |
| 424 FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSP
rimitiveValue* vertical, RenderStyle* style, RenderStyle* rootStyle, const IntSi
ze& size) | 423 FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSP
rimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const
IntSize& size) |
| 425 { | 424 { |
| 426 FloatPoint result; | 425 FloatPoint result; |
| 427 | 426 |
| 428 if (horizontal) | 427 if (horizontal) |
| 429 result.setX(positionFromValue(horizontal, style, rootStyle, size, true))
; | 428 result.setX(positionFromValue(horizontal, conversionData, size, true)); |
| 430 | 429 |
| 431 if (vertical) | 430 if (vertical) |
| 432 result.setY(positionFromValue(vertical, style, rootStyle, size, false)); | 431 result.setY(positionFromValue(vertical, conversionData, size, false)); |
| 433 | 432 |
| 434 return result; | 433 return result; |
| 435 } | 434 } |
| 436 | 435 |
| 437 bool CSSGradientValue::isCacheable() const | 436 bool CSSGradientValue::isCacheable() const |
| 438 { | 437 { |
| 439 for (size_t i = 0; i < m_stops.size(); ++i) { | 438 for (size_t i = 0; i < m_stops.size(); ++i) { |
| 440 const CSSGradientColorStop& stop = m_stops[i]; | 439 const CSSGradientColorStop& stop = m_stops[i]; |
| 441 | 440 |
| 442 if (stop.m_colorIsDerivedFromElement) | 441 if (stop.m_colorIsDerivedFromElement) |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 float endX = c / (slope - perpendicularSlope); | 628 float endX = c / (slope - perpendicularSlope); |
| 630 float endY = perpendicularSlope * endX + c; | 629 float endY = perpendicularSlope * endX + c; |
| 631 | 630 |
| 632 // We computed the end point, so set the second point, | 631 // We computed the end point, so set the second point, |
| 633 // taking into account the moved origin and the fact that we're in drawing s
pace (+y = down). | 632 // taking into account the moved origin and the fact that we're in drawing s
pace (+y = down). |
| 634 secondPoint.set(halfWidth + endX, halfHeight - endY); | 633 secondPoint.set(halfWidth + endX, halfHeight - endY); |
| 635 // Reflect around the center for the start point. | 634 // Reflect around the center for the start point. |
| 636 firstPoint.set(halfWidth - endX, halfHeight + endY); | 635 firstPoint.set(halfWidth - endX, halfHeight + endY); |
| 637 } | 636 } |
| 638 | 637 |
| 639 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(RenderObject* render
er, const IntSize& size) | 638 PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(const CSSToLengthCon
versionData& conversionData, const IntSize& size) |
| 640 { | 639 { |
| 641 ASSERT(!size.isEmpty()); | 640 ASSERT(!size.isEmpty()); |
| 642 | 641 |
| 643 RenderStyle* rootStyle = renderer->document().documentElement()->renderStyle
(); | |
| 644 | |
| 645 FloatPoint firstPoint; | 642 FloatPoint firstPoint; |
| 646 FloatPoint secondPoint; | 643 FloatPoint secondPoint; |
| 647 if (m_angle) { | 644 if (m_angle) { |
| 648 float angle = m_angle->getFloatValue(CSSPrimitiveValue::CSS_DEG); | 645 float angle = m_angle->getFloatValue(CSSPrimitiveValue::CSS_DEG); |
| 649 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType)
; | 646 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType)
; |
| 650 } else { | 647 } else { |
| 651 switch (m_gradientType) { | 648 switch (m_gradientType) { |
| 652 case CSSDeprecatedLinearGradient: | 649 case CSSDeprecatedLinearGradient: |
| 653 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), rendere
r->style(), rootStyle, size); | 650 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), convers
ionData, size); |
| 654 if (m_secondX || m_secondY) | 651 if (m_secondX || m_secondY) |
| 655 secondPoint = computeEndPoint(m_secondX.get(), m_secondY.get(),
renderer->style(), rootStyle, size); | 652 secondPoint = computeEndPoint(m_secondX.get(), m_secondY.get(),
conversionData, size); |
| 656 else { | 653 else { |
| 657 if (m_firstX) | 654 if (m_firstX) |
| 658 secondPoint.setX(size.width() - firstPoint.x()); | 655 secondPoint.setX(size.width() - firstPoint.x()); |
| 659 if (m_firstY) | 656 if (m_firstY) |
| 660 secondPoint.setY(size.height() - firstPoint.y()); | 657 secondPoint.setY(size.height() - firstPoint.y()); |
| 661 } | 658 } |
| 662 break; | 659 break; |
| 663 case CSSPrefixedLinearGradient: | 660 case CSSPrefixedLinearGradient: |
| 664 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), rendere
r->style(), rootStyle, size); | 661 firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), convers
ionData, size); |
| 665 if (m_firstX) | 662 if (m_firstX) |
| 666 secondPoint.setX(size.width() - firstPoint.x()); | 663 secondPoint.setX(size.width() - firstPoint.x()); |
| 667 if (m_firstY) | 664 if (m_firstY) |
| 668 secondPoint.setY(size.height() - firstPoint.y()); | 665 secondPoint.setY(size.height() - firstPoint.y()); |
| 669 break; | 666 break; |
| 670 case CSSLinearGradient: | 667 case CSSLinearGradient: |
| 671 if (m_firstX && m_firstY) { | 668 if (m_firstX && m_firstY) { |
| 672 // "Magic" corners, so the 50% line touches two corners. | 669 // "Magic" corners, so the 50% line touches two corners. |
| 673 float rise = size.width(); | 670 float rise = size.width(); |
| 674 float run = size.height(); | 671 float run = size.height(); |
| 675 if (m_firstX && m_firstX->getValueID() == CSSValueLeft) | 672 if (m_firstX && m_firstX->getValueID() == CSSValueLeft) |
| 676 run *= -1; | 673 run *= -1; |
| 677 if (m_firstY && m_firstY->getValueID() == CSSValueBottom) | 674 if (m_firstY && m_firstY->getValueID() == CSSValueBottom) |
| 678 rise *= -1; | 675 rise *= -1; |
| 679 // Compute angle, and flip it back to "bearing angle" degrees. | 676 // Compute angle, and flip it back to "bearing angle" degrees. |
| 680 float angle = 90 - rad2deg(atan2(rise, run)); | 677 float angle = 90 - rad2deg(atan2(rise, run)); |
| 681 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); | 678 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradi
entType); |
| 682 } else if (m_firstX || m_firstY) { | 679 } else if (m_firstX || m_firstY) { |
| 683 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), re
nderer->style(), rootStyle, size); | 680 secondPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), co
nversionData, size); |
| 684 if (m_firstX) | 681 if (m_firstX) |
| 685 firstPoint.setX(size.width() - secondPoint.x()); | 682 firstPoint.setX(size.width() - secondPoint.x()); |
| 686 if (m_firstY) | 683 if (m_firstY) |
| 687 firstPoint.setY(size.height() - secondPoint.y()); | 684 firstPoint.setY(size.height() - secondPoint.y()); |
| 688 } else | 685 } else |
| 689 secondPoint.setY(size.height()); | 686 secondPoint.setY(size.height()); |
| 690 break; | 687 break; |
| 691 default: | 688 default: |
| 692 ASSERT_NOT_REACHED(); | 689 ASSERT_NOT_REACHED(); |
| 693 } | 690 } |
| 694 | 691 |
| 695 } | 692 } |
| 696 | 693 |
| 697 RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint); | 694 RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint); |
| 698 | 695 |
| 699 gradient->setDrawsInPMColorSpace(true); | 696 gradient->setDrawsInPMColorSpace(true); |
| 700 | 697 |
| 701 // Now add the stops. | 698 // Now add the stops. |
| 702 addStops(gradient.get(), renderer, rootStyle, 1); | 699 addStops(gradient.get(), conversionData, 1); |
| 703 | 700 |
| 704 return gradient.release(); | 701 return gradient.release(); |
| 705 } | 702 } |
| 706 | 703 |
| 707 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const | 704 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const |
| 708 { | 705 { |
| 709 if (m_gradientType == CSSDeprecatedLinearGradient) | 706 if (m_gradientType == CSSDeprecatedLinearGradient) |
| 710 return other.m_gradientType == m_gradientType | 707 return other.m_gradientType == m_gradientType |
| 711 && compareCSSValuePtr(m_firstX, other.m_firstX) | 708 && compareCSSValuePtr(m_firstX, other.m_firstX) |
| 712 && compareCSSValuePtr(m_firstY, other.m_firstY) | 709 && compareCSSValuePtr(m_firstY, other.m_firstY) |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 result.append(stop.m_position->cssText()); | 876 result.append(stop.m_position->cssText()); |
| 880 } | 877 } |
| 881 } | 878 } |
| 882 | 879 |
| 883 } | 880 } |
| 884 | 881 |
| 885 result.append(')'); | 882 result.append(')'); |
| 886 return result.toString(); | 883 return result.toString(); |
| 887 } | 884 } |
| 888 | 885 |
| 889 float CSSRadialGradientValue::resolveRadius(CSSPrimitiveValue* radius, RenderSty
le* style, RenderStyle* rootStyle, float* widthOrHeight) | 886 float CSSRadialGradientValue::resolveRadius(CSSPrimitiveValue* radius, const CSS
ToLengthConversionData& conversionData, float* widthOrHeight) |
| 890 { | 887 { |
| 891 float zoomFactor = style->effectiveZoom(); | |
| 892 | |
| 893 float result = 0; | 888 float result = 0; |
| 894 if (radius->isNumber()) // Can the radius be a percentage? | 889 if (radius->isNumber()) // Can the radius be a percentage? |
| 895 result = radius->getFloatValue() * zoomFactor; | 890 result = radius->getFloatValue() * conversionData.zoom(); |
| 896 else if (widthOrHeight && radius->isPercentage()) | 891 else if (widthOrHeight && radius->isPercentage()) |
| 897 result = *widthOrHeight * radius->getFloatValue() / 100; | 892 result = *widthOrHeight * radius->getFloatValue() / 100; |
| 898 else | 893 else |
| 899 result = radius->computeLength<float>(style, rootStyle, zoomFactor); | 894 result = radius->computeLength<float>(conversionData); |
| 900 | 895 |
| 901 return result; | 896 return result; |
| 902 } | 897 } |
| 903 | 898 |
| 904 static float distanceToClosestCorner(const FloatPoint& p, const FloatSize& size,
FloatPoint& corner) | 899 static float distanceToClosestCorner(const FloatPoint& p, const FloatSize& size,
FloatPoint& corner) |
| 905 { | 900 { |
| 906 FloatPoint topLeft; | 901 FloatPoint topLeft; |
| 907 float topLeftDistance = FloatSize(p - topLeft).diagonalLength(); | 902 float topLeftDistance = FloatSize(p - topLeft).diagonalLength(); |
| 908 | 903 |
| 909 FloatPoint topRight(size.width(), 0); | 904 FloatPoint topRight(size.width(), 0); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 // width/height given by aspectRatio. | 966 // width/height given by aspectRatio. |
| 972 static inline float horizontalEllipseRadius(const FloatSize& p, float aspectRati
o) | 967 static inline float horizontalEllipseRadius(const FloatSize& p, float aspectRati
o) |
| 973 { | 968 { |
| 974 // x^2/a^2 + y^2/b^2 = 1 | 969 // x^2/a^2 + y^2/b^2 = 1 |
| 975 // a/b = aspectRatio, b = a/aspectRatio | 970 // a/b = aspectRatio, b = a/aspectRatio |
| 976 // a = sqrt(x^2 + y^2/(1/r^2)) | 971 // a = sqrt(x^2 + y^2/(1/r^2)) |
| 977 return sqrtf(p.width() * p.width() + (p.height() * p.height()) / (1 / (aspec
tRatio * aspectRatio))); | 972 return sqrtf(p.width() * p.width() + (p.height() * p.height()) / (1 / (aspec
tRatio * aspectRatio))); |
| 978 } | 973 } |
| 979 | 974 |
| 980 // FIXME: share code with the linear version | 975 // FIXME: share code with the linear version |
| 981 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(RenderObject* render
er, const IntSize& size) | 976 PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(const CSSToLengthCon
versionData& conversionData, const IntSize& size) |
| 982 { | 977 { |
| 983 ASSERT(!size.isEmpty()); | 978 ASSERT(!size.isEmpty()); |
| 984 | 979 |
| 985 RenderStyle* rootStyle = renderer->document().documentElement()->renderStyle
(); | 980 FloatPoint firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), conv
ersionData, size); |
| 986 | |
| 987 FloatPoint firstPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), rend
erer->style(), rootStyle, size); | |
| 988 if (!m_firstX) | 981 if (!m_firstX) |
| 989 firstPoint.setX(size.width() / 2); | 982 firstPoint.setX(size.width() / 2); |
| 990 if (!m_firstY) | 983 if (!m_firstY) |
| 991 firstPoint.setY(size.height() / 2); | 984 firstPoint.setY(size.height() / 2); |
| 992 | 985 |
| 993 FloatPoint secondPoint = computeEndPoint(m_secondX.get(), m_secondY.get(), r
enderer->style(), rootStyle, size); | 986 FloatPoint secondPoint = computeEndPoint(m_secondX.get(), m_secondY.get(), c
onversionData, size); |
| 994 if (!m_secondX) | 987 if (!m_secondX) |
| 995 secondPoint.setX(size.width() / 2); | 988 secondPoint.setX(size.width() / 2); |
| 996 if (!m_secondY) | 989 if (!m_secondY) |
| 997 secondPoint.setY(size.height() / 2); | 990 secondPoint.setY(size.height() / 2); |
| 998 | 991 |
| 999 float firstRadius = 0; | 992 float firstRadius = 0; |
| 1000 if (m_firstRadius) | 993 if (m_firstRadius) |
| 1001 firstRadius = resolveRadius(m_firstRadius.get(), renderer->style(), root
Style); | 994 firstRadius = resolveRadius(m_firstRadius.get(), conversionData); |
| 1002 | 995 |
| 1003 float secondRadius = 0; | 996 float secondRadius = 0; |
| 1004 float aspectRatio = 1; // width / height. | 997 float aspectRatio = 1; // width / height. |
| 1005 if (m_secondRadius) | 998 if (m_secondRadius) |
| 1006 secondRadius = resolveRadius(m_secondRadius.get(), renderer->style(), ro
otStyle); | 999 secondRadius = resolveRadius(m_secondRadius.get(), conversionData); |
| 1007 else if (m_endHorizontalSize) { | 1000 else if (m_endHorizontalSize) { |
| 1008 float width = size.width(); | 1001 float width = size.width(); |
| 1009 float height = size.height(); | 1002 float height = size.height(); |
| 1010 secondRadius = resolveRadius(m_endHorizontalSize.get(), renderer->style(
), rootStyle, &width); | 1003 secondRadius = resolveRadius(m_endHorizontalSize.get(), conversionData,
&width); |
| 1011 if (m_endVerticalSize) | 1004 if (m_endVerticalSize) |
| 1012 aspectRatio = secondRadius / resolveRadius(m_endVerticalSize.get(),
renderer->style(), rootStyle, &height); | 1005 aspectRatio = secondRadius / resolveRadius(m_endVerticalSize.get(),
conversionData, &height); |
| 1013 else | 1006 else |
| 1014 aspectRatio = 1; | 1007 aspectRatio = 1; |
| 1015 } else { | 1008 } else { |
| 1016 enum GradientShape { Circle, Ellipse }; | 1009 enum GradientShape { Circle, Ellipse }; |
| 1017 GradientShape shape = Ellipse; | 1010 GradientShape shape = Ellipse; |
| 1018 if ((m_shape && m_shape->getValueID() == CSSValueCircle) | 1011 if ((m_shape && m_shape->getValueID() == CSSValueCircle) |
| 1019 || (!m_shape && !m_sizingBehavior && m_endHorizontalSize && !m_endVe
rticalSize)) | 1012 || (!m_shape && !m_sizingBehavior && m_endHorizontalSize && !m_endVe
rticalSize)) |
| 1020 shape = Circle; | 1013 shape = Circle; |
| 1021 | 1014 |
| 1022 enum GradientFill { ClosestSide, ClosestCorner, FarthestSide, FarthestCo
rner }; | 1015 enum GradientFill { ClosestSide, ClosestCorner, FarthestSide, FarthestCo
rner }; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 gradient->setDrawsInPMColorSpace(true); | 1103 gradient->setDrawsInPMColorSpace(true); |
| 1111 | 1104 |
| 1112 // addStops() only uses maxExtent for repeating gradients. | 1105 // addStops() only uses maxExtent for repeating gradients. |
| 1113 float maxExtent = 0; | 1106 float maxExtent = 0; |
| 1114 if (m_repeating) { | 1107 if (m_repeating) { |
| 1115 FloatPoint corner; | 1108 FloatPoint corner; |
| 1116 maxExtent = distanceToFarthestCorner(secondPoint, size, corner); | 1109 maxExtent = distanceToFarthestCorner(secondPoint, size, corner); |
| 1117 } | 1110 } |
| 1118 | 1111 |
| 1119 // Now add the stops. | 1112 // Now add the stops. |
| 1120 addStops(gradient.get(), renderer, rootStyle, maxExtent); | 1113 addStops(gradient.get(), conversionData, maxExtent); |
| 1121 | 1114 |
| 1122 return gradient.release(); | 1115 return gradient.release(); |
| 1123 } | 1116 } |
| 1124 | 1117 |
| 1125 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const | 1118 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const |
| 1126 { | 1119 { |
| 1127 if (m_gradientType == CSSDeprecatedRadialGradient) | 1120 if (m_gradientType == CSSDeprecatedRadialGradient) |
| 1128 return other.m_gradientType == m_gradientType | 1121 return other.m_gradientType == m_gradientType |
| 1129 && compareCSSValuePtr(m_firstX, other.m_firstX) | 1122 && compareCSSValuePtr(m_firstX, other.m_firstX) |
| 1130 && compareCSSValuePtr(m_firstY, other.m_firstY) | 1123 && compareCSSValuePtr(m_firstY, other.m_firstY) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 equalHorizontalAndVerticalSize = compareCSSValuePtr(m_endHorizontalSize,
other.m_endHorizontalSize) && compareCSSValuePtr(m_endVerticalSize, other.m_end
VerticalSize); | 1155 equalHorizontalAndVerticalSize = compareCSSValuePtr(m_endHorizontalSize,
other.m_endHorizontalSize) && compareCSSValuePtr(m_endVerticalSize, other.m_end
VerticalSize); |
| 1163 else { | 1156 else { |
| 1164 equalShape = !other.m_shape; | 1157 equalShape = !other.m_shape; |
| 1165 equalSizingBehavior = !other.m_sizingBehavior; | 1158 equalSizingBehavior = !other.m_sizingBehavior; |
| 1166 equalHorizontalAndVerticalSize = !other.m_endHorizontalSize && !other.m_
endVerticalSize; | 1159 equalHorizontalAndVerticalSize = !other.m_endHorizontalSize && !other.m_
endVerticalSize; |
| 1167 } | 1160 } |
| 1168 return equalShape && equalSizingBehavior && equalHorizontalAndVerticalSize &
& m_stops == other.m_stops; | 1161 return equalShape && equalSizingBehavior && equalHorizontalAndVerticalSize &
& m_stops == other.m_stops; |
| 1169 } | 1162 } |
| 1170 | 1163 |
| 1171 } // namespace WebCore | 1164 } // namespace WebCore |
| OLD | NEW |