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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 Color color; | 107 Color color; |
108 float offset; | 108 float offset; |
109 bool specified; | 109 bool specified; |
110 | 110 |
111 GradientStop() | 111 GradientStop() |
112 : offset(0) | 112 : offset(0) |
113 , specified(false) | 113 , specified(false) |
114 { } | 114 { } |
115 }; | 115 }; |
116 | 116 |
117 PassRefPtrWillBeRawPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesRes
olved(const TextLinkColors& textLinkColors, Color currentColor) | 117 void replaceColorHintsWithColorStops(WillBeHeapVector<GradientStop>& stops, cons
t WillBeHeapVector<CSSGradientColorStop, 2>& cssGradientStops) |
118 { | |
119 bool derived = false; | |
120 for (auto& stop : m_stops) { | |
121 if (!stop.isHint() && stop.m_color->colorIsDerivedFromElement()) { | |
122 stop.m_colorIsDerivedFromElement = true; | |
123 derived = true; | |
124 break; | |
125 } | |
126 } | |
127 | |
128 RefPtrWillBeRawPtr<CSSGradientValue> result = nullptr; | |
129 if (!derived) | |
130 result = this; | |
131 else if (isLinearGradientValue()) | |
132 result = toCSSLinearGradientValue(this)->clone(); | |
133 else if (isRadialGradientValue()) | |
134 result = toCSSRadialGradientValue(this)->clone(); | |
135 else { | |
136 ASSERT_NOT_REACHED(); | |
137 return nullptr; | |
138 } | |
139 | |
140 for (auto& stop : result->m_stops) { | |
141 if (!stop.isHint()) | |
142 stop.m_resolvedColor = textLinkColors.colorFromPrimitiveValue(stop.m
_color.get(), currentColor); | |
143 } | |
144 | |
145 return result.release(); | |
146 } | |
147 | |
148 static void replaceColorHintsWithColorStops(WillBeHeapVector<GradientStop>& stop
s, const WillBeHeapVector<CSSGradientColorStop, 2>& cssGradientStops) | |
149 { | 118 { |
150 // This algorithm will replace each color interpolation hint with 9 regular | 119 // This algorithm will replace each color interpolation hint with 9 regular |
151 // color stops. The color values for the new color stops will be calculated | 120 // color stops. The color values for the new color stops will be calculated |
152 // using the color weighting formula defined in the spec. The new color | 121 // using the color weighting formula defined in the spec. The new color |
153 // stops will be positioned in such a way that all the pixels between the tw
o | 122 // stops will be positioned in such a way that all the pixels between the tw
o |
154 // user defined color stops have color values close to the interpolation cur
ve. | 123 // user defined color stops have color values close to the interpolation cur
ve. |
155 // If the hint is closer to the left color stop, add 2 stops to the left and | 124 // If the hint is closer to the left color stop, add 2 stops to the left and |
156 // 6 to the right, else add 6 stops to the left and 2 to the right. | 125 // 6 to the right, else add 6 stops to the left and 2 to the right. |
157 // The color stops on the side with more space start midway because | 126 // The color stops on the side with more space start midway because |
158 // the curve approximates a line in that region. | 127 // the curve approximates a line in that region. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 newStops[y].color = blend(leftColor, rightColor, weighting); | 195 newStops[y].color = blend(leftColor, rightColor, weighting); |
227 } | 196 } |
228 | 197 |
229 // Replace the color hint with the new color stops. | 198 // Replace the color hint with the new color stops. |
230 stops.remove(x); | 199 stops.remove(x); |
231 stops.insert(x, newStops, 9); | 200 stops.insert(x, newStops, 9); |
232 indexOffset += 8; | 201 indexOffset += 8; |
233 } | 202 } |
234 } | 203 } |
235 | 204 |
| 205 static Color resolveStopColor(CSSPrimitiveValue* stopColor, const RenderObject&
object) |
| 206 { |
| 207 return object.document().textLinkColors().colorFromPrimitiveValue(stopColor,
object.resolveColor(CSSPropertyColor)); |
| 208 } |
| 209 |
236 void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
ata& conversionData, float maxLengthForRepeat, const RenderObject& object) | 210 void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
ata& conversionData, float maxLengthForRepeat, const RenderObject& object) |
237 { | 211 { |
238 if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDe
precatedRadialGradient) { | 212 if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDe
precatedRadialGradient) { |
239 sortStopsIfNeeded(); | 213 sortStopsIfNeeded(); |
240 | 214 |
241 for (unsigned i = 0; i < m_stops.size(); i++) { | 215 for (unsigned i = 0; i < m_stops.size(); i++) { |
242 const CSSGradientColorStop& stop = m_stops[i]; | 216 const CSSGradientColorStop& stop = m_stops[i]; |
243 | 217 |
244 float offset; | 218 float offset; |
245 if (stop.m_position->isPercentage()) | 219 if (stop.m_position->isPercentage()) |
246 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_P
ERCENTAGE) / 100; | 220 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_P
ERCENTAGE) / 100; |
247 else | 221 else |
248 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_N
UMBER); | 222 offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_N
UMBER); |
249 | 223 |
250 gradient->addColorStop(offset, stop.m_resolvedColor); | 224 gradient->addColorStop(offset, resolveStopColor(stop.m_color.get(),
object)); |
251 } | 225 } |
252 | 226 |
253 return; | 227 return; |
254 } | 228 } |
255 | 229 |
256 size_t numStops = m_stops.size(); | 230 size_t numStops = m_stops.size(); |
257 | 231 |
258 WillBeHeapVector<GradientStop> stops(numStops); | 232 WillBeHeapVector<GradientStop> stops(numStops); |
259 | 233 |
260 float gradientLength = 0; | 234 float gradientLength = 0; |
261 bool computedGradientLength = false; | 235 bool computedGradientLength = false; |
262 | 236 |
263 bool hasHints = false; | 237 bool hasHints = false; |
264 | 238 |
265 FloatPoint gradientStart = gradient->p0(); | 239 FloatPoint gradientStart = gradient->p0(); |
266 FloatPoint gradientEnd; | 240 FloatPoint gradientEnd; |
267 if (isLinearGradientValue()) | 241 if (isLinearGradientValue()) |
268 gradientEnd = gradient->p1(); | 242 gradientEnd = gradient->p1(); |
269 else if (isRadialGradientValue()) | 243 else if (isRadialGradientValue()) |
270 gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0); | 244 gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0); |
271 | 245 |
272 for (size_t i = 0; i < numStops; ++i) { | 246 for (size_t i = 0; i < numStops; ++i) { |
273 const CSSGradientColorStop& stop = m_stops[i]; | 247 const CSSGradientColorStop& stop = m_stops[i]; |
274 | 248 |
275 if (stop.isHint()) | 249 if (stop.isHint()) |
276 hasHints = true; | 250 hasHints = true; |
277 else | 251 else |
278 stops[i].color = object.document().textLinkColors().colorFromPrimiti
veValue(stop.m_color.get(), object.style()->visitedDependentColor(CSSPropertyCol
or)); | 252 stops[i].color = resolveStopColor(stop.m_color.get(), object); |
279 | 253 |
280 if (stop.m_position) { | 254 if (stop.m_position) { |
281 if (stop.m_position->isPercentage()) | 255 if (stop.m_position->isPercentage()) |
282 stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveVal
ue::CSS_PERCENTAGE) / 100; | 256 stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveVal
ue::CSS_PERCENTAGE) / 100; |
283 else if (stop.m_position->isLength() || stop.m_position->isCalculate
dPercentageWithLength()) { | 257 else if (stop.m_position->isLength() || stop.m_position->isCalculate
dPercentageWithLength()) { |
284 if (!computedGradientLength) { | 258 if (!computedGradientLength) { |
285 FloatSize gradientSize(gradientStart - gradientEnd); | 259 FloatSize gradientSize(gradientStart - gradientEnd); |
286 gradientLength = gradientSize.diagonalLength(); | 260 gradientLength = gradientSize.diagonalLength(); |
287 } | 261 } |
288 float length; | 262 float length; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 result.setY(positionFromValue(vertical, conversionData, size, false)); | 526 result.setY(positionFromValue(vertical, conversionData, size, false)); |
553 | 527 |
554 return result; | 528 return result; |
555 } | 529 } |
556 | 530 |
557 bool CSSGradientValue::isCacheable() const | 531 bool CSSGradientValue::isCacheable() const |
558 { | 532 { |
559 for (size_t i = 0; i < m_stops.size(); ++i) { | 533 for (size_t i = 0; i < m_stops.size(); ++i) { |
560 const CSSGradientColorStop& stop = m_stops[i]; | 534 const CSSGradientColorStop& stop = m_stops[i]; |
561 | 535 |
562 if (stop.m_colorIsDerivedFromElement) | 536 if (!stop.isHint() && stop.m_color->colorIsDerivedFromElement()) |
563 return false; | 537 return false; |
564 | 538 |
565 if (!stop.m_position) | 539 if (!stop.m_position) |
566 continue; | 540 continue; |
567 | 541 |
568 if (stop.m_position->isFontRelativeLength()) | 542 if (stop.m_position->isFontRelativeLength()) |
569 return false; | 543 return false; |
570 } | 544 } |
571 | 545 |
572 return true; | 546 return true; |
573 } | 547 } |
574 | 548 |
575 bool CSSGradientValue::knownToBeOpaque(const RenderObject*) const | 549 bool CSSGradientValue::knownToBeOpaque(const RenderObject* object) const |
576 { | 550 { |
| 551 ASSERT(object); |
577 for (auto& stop : m_stops) { | 552 for (auto& stop : m_stops) { |
578 if (!stop.isHint() && stop.m_resolvedColor.hasAlpha()) | 553 if (!stop.isHint() && resolveStopColor(stop.m_color.get(), *object).hasA
lpha()) |
579 return false; | 554 return false; |
580 } | 555 } |
581 return true; | 556 return true; |
582 } | 557 } |
583 | 558 |
584 void CSSGradientValue::traceAfterDispatch(Visitor* visitor) | 559 void CSSGradientValue::traceAfterDispatch(Visitor* visitor) |
585 { | 560 { |
586 visitor->trace(m_firstX); | 561 visitor->trace(m_firstX); |
587 visitor->trace(m_firstY); | 562 visitor->trace(m_firstY); |
588 visitor->trace(m_secondX); | 563 visitor->trace(m_secondX); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 visitor->trace(m_firstRadius); | 1280 visitor->trace(m_firstRadius); |
1306 visitor->trace(m_secondRadius); | 1281 visitor->trace(m_secondRadius); |
1307 visitor->trace(m_shape); | 1282 visitor->trace(m_shape); |
1308 visitor->trace(m_sizingBehavior); | 1283 visitor->trace(m_sizingBehavior); |
1309 visitor->trace(m_endHorizontalSize); | 1284 visitor->trace(m_endHorizontalSize); |
1310 visitor->trace(m_endVerticalSize); | 1285 visitor->trace(m_endVerticalSize); |
1311 CSSGradientValue::traceAfterDispatch(visitor); | 1286 CSSGradientValue::traceAfterDispatch(visitor); |
1312 } | 1287 } |
1313 | 1288 |
1314 } // namespace blink | 1289 } // namespace blink |
OLD | NEW |