| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 switch (valueID) { | 54 switch (valueID) { |
| 55 case CSSValueInternalQuirkInherit: | 55 case CSSValueInternalQuirkInherit: |
| 56 case CSSValueWebkitLink: | 56 case CSSValueWebkitLink: |
| 57 case CSSValueWebkitActivelink: | 57 case CSSValueWebkitActivelink: |
| 58 case CSSValueCurrentcolor: | 58 case CSSValueCurrentcolor: |
| 59 return true; | 59 return true; |
| 60 default: | 60 default: |
| 61 return false; | 61 return false; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 |
| 65 bool appendPosition(StringBuilder& result, |
| 66 const CSSValue* x, |
| 67 const CSSValue* y, |
| 68 bool wroteSomething) { |
| 69 if (!x && !y) |
| 70 return false; |
| 71 |
| 72 if (wroteSomething) |
| 73 result.append(' '); |
| 74 result.append("at "); |
| 75 |
| 76 if (x) { |
| 77 result.append(x->cssText()); |
| 78 if (y) |
| 79 result.append(' '); |
| 80 } |
| 81 |
| 82 if (y) |
| 83 result.append(y->cssText()); |
| 84 |
| 85 return true; |
| 86 } |
| 64 } | 87 } |
| 65 | 88 |
| 66 DEFINE_TRACE(CSSGradientColorStop) { | 89 DEFINE_TRACE(CSSGradientColorStop) { |
| 67 visitor->trace(m_position); | 90 visitor->trace(m_position); |
| 68 visitor->trace(m_color); | 91 visitor->trace(m_color); |
| 69 } | 92 } |
| 70 | 93 |
| 71 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, | 94 PassRefPtr<Image> CSSGradientValue::image(const LayoutObject& layoutObject, |
| 72 const IntSize& size) { | 95 const IntSize& size) { |
| 73 if (size.isEmpty()) | 96 if (size.isEmpty()) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 86 } | 109 } |
| 87 | 110 |
| 88 // We need to create an image. | 111 // We need to create an image. |
| 89 RefPtr<Gradient> gradient; | 112 RefPtr<Gradient> gradient; |
| 90 | 113 |
| 91 const ComputedStyle* rootStyle = | 114 const ComputedStyle* rootStyle = |
| 92 layoutObject.document().documentElement()->computedStyle(); | 115 layoutObject.document().documentElement()->computedStyle(); |
| 93 CSSToLengthConversionData conversionData( | 116 CSSToLengthConversionData conversionData( |
| 94 layoutObject.style(), rootStyle, LayoutViewItem(layoutObject.view()), | 117 layoutObject.style(), rootStyle, LayoutViewItem(layoutObject.view()), |
| 95 layoutObject.style()->effectiveZoom()); | 118 layoutObject.style()->effectiveZoom()); |
| 96 if (isLinearGradientValue()) | 119 |
| 97 gradient = toCSSLinearGradientValue(this)->createGradient( | 120 switch (getClassType()) { |
| 98 conversionData, size, layoutObject); | 121 case LinearGradientClass: |
| 99 else | 122 gradient = toCSSLinearGradientValue(this)->createGradient( |
| 100 gradient = toCSSRadialGradientValue(this)->createGradient( | 123 conversionData, size, layoutObject); |
| 101 conversionData, size, layoutObject); | 124 break; |
| 125 case RadialGradientClass: |
| 126 gradient = toCSSRadialGradientValue(this)->createGradient( |
| 127 conversionData, size, layoutObject); |
| 128 break; |
| 129 case ConicGradientClass: |
| 130 gradient = toCSSConicGradientValue(this)->createGradient( |
| 131 conversionData, size, layoutObject); |
| 132 break; |
| 133 default: |
| 134 NOTREACHED(); |
| 135 } |
| 102 | 136 |
| 103 RefPtr<Image> newImage = GradientGeneratedImage::create(gradient, size); | 137 RefPtr<Image> newImage = GradientGeneratedImage::create(gradient, size); |
| 104 if (cacheable) | 138 if (cacheable) |
| 105 putImage(size, newImage); | 139 putImage(size, newImage); |
| 106 | 140 |
| 107 return newImage.release(); | 141 return newImage.release(); |
| 108 } | 142 } |
| 109 | 143 |
| 110 // Should only ever be called for deprecated gradients. | 144 // Should only ever be called for deprecated gradients. |
| 111 static inline bool compareStops(const CSSGradientColorStop& a, | 145 static inline bool compareStops(const CSSGradientColorStop& a, |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 else if (stop.m_position->isLength() || | 474 else if (stop.m_position->isLength() || |
| 441 stop.m_position->isCalculatedPercentageWithLength()) { | 475 stop.m_position->isCalculatedPercentageWithLength()) { |
| 442 float length; | 476 float length; |
| 443 if (stop.m_position->isLength()) | 477 if (stop.m_position->isLength()) |
| 444 length = stop.m_position->computeLength<float>(conversionData); | 478 length = stop.m_position->computeLength<float>(conversionData); |
| 445 else | 479 else |
| 446 length = stop.m_position->cssCalcValue() | 480 length = stop.m_position->cssCalcValue() |
| 447 ->toCalcValue(conversionData) | 481 ->toCalcValue(conversionData) |
| 448 ->evaluate(gradientLength); | 482 ->evaluate(gradientLength); |
| 449 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; | 483 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; |
| 484 } else if (stop.m_position->isAngle()) { |
| 485 stops[i].offset = stop.m_position->computeDegrees() / 360.0f; |
| 450 } else { | 486 } else { |
| 451 ASSERT_NOT_REACHED(); | 487 ASSERT_NOT_REACHED(); |
| 452 stops[i].offset = 0; | 488 stops[i].offset = 0; |
| 453 } | 489 } |
| 454 stops[i].specified = true; | 490 stops[i].specified = true; |
| 455 } else { | 491 } else { |
| 456 // If the first color-stop does not have a position, its position defaults | 492 // If the first color-stop does not have a position, its position defaults |
| 457 // to 0%. If the last color-stop does not have a position, its position | 493 // to 0%. If the last color-stop does not have a position, its position |
| 458 // defaults to 100%. | 494 // defaults to 100%. |
| 459 if (!i) { | 495 if (!i) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 result.append(m_firstX->cssText()); | 768 result.append(m_firstX->cssText()); |
| 733 result.append(' '); | 769 result.append(' '); |
| 734 result.append(m_firstY->cssText()); | 770 result.append(m_firstY->cssText()); |
| 735 } else if (m_firstX) | 771 } else if (m_firstX) |
| 736 result.append(m_firstX->cssText()); | 772 result.append(m_firstX->cssText()); |
| 737 else | 773 else |
| 738 result.append(m_firstY->cssText()); | 774 result.append(m_firstY->cssText()); |
| 739 wroteSomething = true; | 775 wroteSomething = true; |
| 740 } | 776 } |
| 741 | 777 |
| 742 if (wroteSomething) | 778 appendCSSTextForColorStops(result, wroteSomething); |
| 743 result.append(", "); | |
| 744 | |
| 745 for (unsigned i = 0; i < m_stops.size(); i++) { | |
| 746 const CSSGradientColorStop& stop = m_stops[i]; | |
| 747 if (i) | |
| 748 result.append(", "); | |
| 749 if (stop.m_color) | |
| 750 result.append(stop.m_color->cssText()); | |
| 751 if (stop.m_color && stop.m_position) | |
| 752 result.append(' '); | |
| 753 if (stop.m_position) | |
| 754 result.append(stop.m_position->cssText()); | |
| 755 } | |
| 756 } | 779 } |
| 757 | 780 |
| 758 result.append(')'); | 781 result.append(')'); |
| 759 return result.toString(); | 782 return result.toString(); |
| 760 } | 783 } |
| 761 | 784 |
| 762 // Compute the endpoints so that a gradient of the given angle covers a box of | 785 // Compute the endpoints so that a gradient of the given angle covers a box of |
| 763 // the given size. | 786 // the given size. |
| 764 static void endPointsFromAngle(float angleDeg, | 787 static void endPointsFromAngle(float angleDeg, |
| 765 const IntSize& size, | 788 const IntSize& size, |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 } | 966 } |
| 944 | 967 |
| 945 return equalXandY && m_stops == other.m_stops; | 968 return equalXandY && m_stops == other.m_stops; |
| 946 } | 969 } |
| 947 | 970 |
| 948 DEFINE_TRACE_AFTER_DISPATCH(CSSLinearGradientValue) { | 971 DEFINE_TRACE_AFTER_DISPATCH(CSSLinearGradientValue) { |
| 949 visitor->trace(m_angle); | 972 visitor->trace(m_angle); |
| 950 CSSGradientValue::traceAfterDispatch(visitor); | 973 CSSGradientValue::traceAfterDispatch(visitor); |
| 951 } | 974 } |
| 952 | 975 |
| 953 inline void CSSGradientValue::appendCSSTextForDeprecatedColorStops( | 976 void CSSGradientValue::appendCSSTextForColorStops( |
| 977 StringBuilder& result, |
| 978 bool requiresSeparator) const { |
| 979 if (requiresSeparator) |
| 980 result.append(", "); |
| 981 |
| 982 for (unsigned i = 0; i < m_stops.size(); i++) { |
| 983 const CSSGradientColorStop& stop = m_stops[i]; |
| 984 if (i) |
| 985 result.append(", "); |
| 986 if (stop.m_color) |
| 987 result.append(stop.m_color->cssText()); |
| 988 if (stop.m_color && stop.m_position) |
| 989 result.append(' '); |
| 990 if (stop.m_position) |
| 991 result.append(stop.m_position->cssText()); |
| 992 } |
| 993 } |
| 994 |
| 995 void CSSGradientValue::appendCSSTextForDeprecatedColorStops( |
| 954 StringBuilder& result) const { | 996 StringBuilder& result) const { |
| 955 for (unsigned i = 0; i < m_stops.size(); i++) { | 997 for (unsigned i = 0; i < m_stops.size(); i++) { |
| 956 const CSSGradientColorStop& stop = m_stops[i]; | 998 const CSSGradientColorStop& stop = m_stops[i]; |
| 957 result.append(", "); | 999 result.append(", "); |
| 958 if (stop.m_position->getDoubleValue() == 0) { | 1000 if (stop.m_position->getDoubleValue() == 0) { |
| 959 result.append("from("); | 1001 result.append("from("); |
| 960 result.append(stop.m_color->cssText()); | 1002 result.append(stop.m_color->cssText()); |
| 961 result.append(')'); | 1003 result.append(')'); |
| 962 } else if (stop.m_position->getDoubleValue() == 1) { | 1004 } else if (stop.m_position->getDoubleValue() == 1) { |
| 963 result.append("to("); | 1005 result.append("to("); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 if (wroteSomething) | 1105 if (wroteSomething) |
| 1064 result.append(' '); | 1106 result.append(' '); |
| 1065 result.append(m_endHorizontalSize->cssText()); | 1107 result.append(m_endHorizontalSize->cssText()); |
| 1066 if (m_endVerticalSize) { | 1108 if (m_endVerticalSize) { |
| 1067 result.append(' '); | 1109 result.append(' '); |
| 1068 result.append(m_endVerticalSize->cssText()); | 1110 result.append(m_endVerticalSize->cssText()); |
| 1069 } | 1111 } |
| 1070 wroteSomething = true; | 1112 wroteSomething = true; |
| 1071 } | 1113 } |
| 1072 | 1114 |
| 1073 if (m_firstX || m_firstY) { | 1115 wroteSomething |= |
| 1074 if (wroteSomething) | 1116 appendPosition(result, m_firstX, m_firstY, wroteSomething); |
| 1075 result.append(' '); | |
| 1076 result.append("at "); | |
| 1077 if (m_firstX && m_firstY) { | |
| 1078 result.append(m_firstX->cssText()); | |
| 1079 result.append(' '); | |
| 1080 result.append(m_firstY->cssText()); | |
| 1081 } else if (m_firstX) | |
| 1082 result.append(m_firstX->cssText()); | |
| 1083 else | |
| 1084 result.append(m_firstY->cssText()); | |
| 1085 wroteSomething = true; | |
| 1086 } | |
| 1087 | 1117 |
| 1088 if (wroteSomething) | 1118 appendCSSTextForColorStops(result, wroteSomething); |
| 1089 result.append(", "); | |
| 1090 | |
| 1091 for (unsigned i = 0; i < m_stops.size(); i++) { | |
| 1092 const CSSGradientColorStop& stop = m_stops[i]; | |
| 1093 if (i) | |
| 1094 result.append(", "); | |
| 1095 if (stop.m_color) | |
| 1096 result.append(stop.m_color->cssText()); | |
| 1097 if (stop.m_color && stop.m_position) | |
| 1098 result.append(' '); | |
| 1099 if (stop.m_position) | |
| 1100 result.append(stop.m_position->cssText()); | |
| 1101 } | |
| 1102 } | 1119 } |
| 1103 | 1120 |
| 1104 result.append(')'); | 1121 result.append(')'); |
| 1105 return result.toString(); | 1122 return result.toString(); |
| 1106 } | 1123 } |
| 1107 | 1124 |
| 1108 float CSSRadialGradientValue::resolveRadius( | 1125 float CSSRadialGradientValue::resolveRadius( |
| 1109 CSSPrimitiveValue* radius, | 1126 CSSPrimitiveValue* radius, |
| 1110 const CSSToLengthConversionData& conversionData, | 1127 const CSSToLengthConversionData& conversionData, |
| 1111 float* widthOrHeight) { | 1128 float* widthOrHeight) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 DEFINE_TRACE_AFTER_DISPATCH(CSSRadialGradientValue) { | 1355 DEFINE_TRACE_AFTER_DISPATCH(CSSRadialGradientValue) { |
| 1339 visitor->trace(m_firstRadius); | 1356 visitor->trace(m_firstRadius); |
| 1340 visitor->trace(m_secondRadius); | 1357 visitor->trace(m_secondRadius); |
| 1341 visitor->trace(m_shape); | 1358 visitor->trace(m_shape); |
| 1342 visitor->trace(m_sizingBehavior); | 1359 visitor->trace(m_sizingBehavior); |
| 1343 visitor->trace(m_endHorizontalSize); | 1360 visitor->trace(m_endHorizontalSize); |
| 1344 visitor->trace(m_endVerticalSize); | 1361 visitor->trace(m_endVerticalSize); |
| 1345 CSSGradientValue::traceAfterDispatch(visitor); | 1362 CSSGradientValue::traceAfterDispatch(visitor); |
| 1346 } | 1363 } |
| 1347 | 1364 |
| 1365 String CSSConicGradientValue::customCSSText() const { |
| 1366 StringBuilder result; |
| 1367 |
| 1368 if (m_repeating) |
| 1369 result.append("repeating-"); |
| 1370 result.append("conic-gradient("); |
| 1371 |
| 1372 bool wroteSomething = false; |
| 1373 |
| 1374 if (m_fromAngle) { |
| 1375 result.append("from "); |
| 1376 result.append(m_fromAngle->cssText()); |
| 1377 wroteSomething = true; |
| 1378 } |
| 1379 |
| 1380 wroteSomething |= appendPosition(result, m_firstX, m_firstY, wroteSomething); |
| 1381 |
| 1382 appendCSSTextForColorStops(result, wroteSomething); |
| 1383 |
| 1384 result.append(')'); |
| 1385 return result.toString(); |
| 1386 } |
| 1387 |
| 1388 PassRefPtr<Gradient> CSSConicGradientValue::createGradient( |
| 1389 const CSSToLengthConversionData& conversionData, |
| 1390 const IntSize& size, |
| 1391 const LayoutObject& object) { |
| 1392 DCHECK(!size.isEmpty()); |
| 1393 |
| 1394 // TODO(fmalita): implement |
| 1395 return Gradient::create(FloatPoint(), FloatPoint()); |
| 1396 } |
| 1397 |
| 1398 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const { |
| 1399 return m_repeating == other.m_repeating && |
| 1400 dataEquivalent(m_firstX, other.m_firstX) && |
| 1401 dataEquivalent(m_firstY, other.m_firstY) && |
| 1402 dataEquivalent(m_fromAngle, other.m_fromAngle) && |
| 1403 m_stops == other.m_stops; |
| 1404 } |
| 1405 |
| 1406 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { |
| 1407 visitor->trace(m_fromAngle); |
| 1408 CSSGradientValue::traceAfterDispatch(visitor); |
| 1409 } |
| 1410 |
| 1348 } // namespace blink | 1411 } // namespace blink |
| OLD | NEW |