Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/core/css/CSSGradientValue.cpp

Issue 2775103002: Conic gradient parsing support (Closed)
Patch Set: from <angle> support Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 auto wroteSomething = false;
fs 2017/03/28 15:59:20 s/auto/bool/ - really =)
f(malita) 2017/03/28 17:16:45 Heh, it does read weird (leftover from prev patch
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 {
fs 2017/03/28 15:59:20 Should check at least m_repeating too I think (pos
f(malita) 2017/03/28 17:16:45 Good catch, done.
1399 return dataEquivalent(m_firstX, other.m_firstX) &&
1400 dataEquivalent(m_firstY, other.m_firstY) &&
1401 dataEquivalent(m_fromAngle, other.m_fromAngle) &&
1402 m_stops == other.m_stops;
1403 }
1404
1405 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) {
1406 visitor->trace(m_fromAngle);
1407 CSSGradientValue::traceAfterDispatch(visitor);
1408 }
1409
1348 } // namespace blink 1410 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698