| 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 |