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 |