Changeset 257966 in webkit for trunk/Source/WebCore/css/CSSGradientValue.cpp
- Timestamp:
- Mar 5, 2020, 8:11:39 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/css/CSSGradientValue.cpp
r255559 r257966 64 64 auto newImage = GradientImage::create(createGradient(*this, renderer, size), size); 65 65 if (cacheable) 66 saveCachedImageForSize(size, newImage .get());66 saveCachedImageForSize(size, newImage); 67 67 return newImage; 68 }69 70 // Should only ever be called for deprecated gradients.71 static inline bool compareStops(const CSSGradientColorStop& a, const CSSGradientColorStop& b)72 {73 double aVal = a.m_position->doubleValue(CSSUnitType::CSS_NUMBER);74 double bVal = b.m_position->doubleValue(CSSUnitType::CSS_NUMBER);75 76 return aVal < bVal;77 }78 79 void CSSGradientValue::sortStopsIfNeeded()80 {81 ASSERT(m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient);82 if (!m_stopsSorted) {83 if (m_stops.size())84 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);85 m_stopsSorted = true;86 }87 68 } 88 69 89 70 struct GradientStop { 90 71 Color color; 91 float offset { 0 }; 92 bool specified { false }; 93 bool isMidpoint { false }; 72 Optional<float> offset; 73 74 bool isSpecified() const { return offset.hasValue(); } 75 bool isMidpoint() const { return !color.isValid(); } 94 76 }; 95 77 … … 104 86 } 105 87 106 template<typename Function> 107 void resolveStopColors(Vector<CSSGradientColorStop, 2>& stops, Function&& colorResolveFunction) 108 { 109 for (size_t i = 0; i < stops.size(); ++i) { 110 auto& stop = stops[i]; 111 if (stop.isMidpoint) 112 continue; 113 if (stop.m_color) 114 stop.m_resolvedColor = colorResolveFunction(*stop.m_color); 115 else if (i) { 116 auto& previousStop = stops[i - 1]; 117 ASSERT(previousStop.m_color); 118 stop.m_color = previousStop.m_color; 119 stop.m_resolvedColor = previousStop.m_resolvedColor; 120 } 121 } 88 template<typename Function> void resolveStopColors(Vector<CSSGradientColorStop, 2>& stops, Function&& colorResolveFunction) 89 { 90 for (auto& stop : stops) { 91 if (stop.color) 92 stop.resolvedColor = colorResolveFunction(*stop.color); 93 } 94 } 95 96 bool CSSGradientValue::hasColorDerivedFromElement() const 97 { 98 if (!m_hasColorDerivedFromElement) { 99 m_hasColorDerivedFromElement = false; 100 for (auto& stop : m_stops) { 101 if (stop.color && Style::BuilderState::isColorFromPrimitiveValueDerivedFromElement(*stop.color)) { 102 m_hasColorDerivedFromElement = true; 103 break; 104 } 105 } 106 } 107 return *m_hasColorDerivedFromElement; 122 108 } 123 109 124 110 Ref<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(Style::BuilderState& builderState) 125 111 { 126 bool colorIsDerivedFromElement = false; 127 for (auto& stop : m_stops) { 128 if (!stop.isMidpoint && stop.m_color && Style::BuilderState::isColorFromPrimitiveValueDerivedFromElement(*stop.m_color)) { 129 stop.m_colorIsDerivedFromElement = true; 130 colorIsDerivedFromElement = true; 131 break; 132 } 133 } 134 auto result = colorIsDerivedFromElement ? clone(*this) : makeRef(*this); 112 auto result = hasColorDerivedFromElement() ? clone(*this) : makeRef(*this); 135 113 resolveStopColors(result->m_stops, [&](const CSSPrimitiveValue& colorValue) { 136 114 return builderState.colorFromPrimitiveValue(colorValue); … … 153 131 { 154 132 } 155 133 156 134 float gradientLength() const 157 135 { … … 163 141 void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops) 164 142 { 165 float firstOffset = stops.first().offset;166 float lastOffset = stops.last().offset;143 float firstOffset = *stops.first().offset; 144 float lastOffset = *stops.last().offset; 167 145 if (firstOffset != lastOffset) { 168 146 float scale = lastOffset - firstOffset; 169 147 170 148 for (auto& stop : stops) 171 stop.offset = ( stop.offset - firstOffset) / scale;149 stop.offset = (*stop.offset - firstOffset) / scale; 172 150 173 151 auto p0 = m_data.point0; … … 210 188 // Rather than scaling the points < 0, we truncate them, so only scale according to the largest point. 211 189 float firstOffset = 0; 212 float lastOffset = stops.last().offset;190 float lastOffset = *stops.last().offset; 213 191 float scale = lastOffset - firstOffset; 214 192 … … 216 194 size_t firstZeroOrGreaterIndex = numStops; 217 195 for (size_t i = 0; i < numStops; ++i) { 218 if ( stops[i].offset >= 0) {196 if (*stops[i].offset >= 0) { 219 197 firstZeroOrGreaterIndex = i; 220 198 break; … … 223 201 224 202 if (firstZeroOrGreaterIndex > 0) { 225 if (firstZeroOrGreaterIndex < numStops && stops[firstZeroOrGreaterIndex].offset > 0) {226 float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;227 float nextOffset = stops[firstZeroOrGreaterIndex].offset;203 if (firstZeroOrGreaterIndex < numStops && *stops[firstZeroOrGreaterIndex].offset > 0) { 204 float prevOffset = *stops[firstZeroOrGreaterIndex - 1].offset; 205 float nextOffset = *stops[firstZeroOrGreaterIndex].offset; 228 206 229 207 float interStopProportion = -prevOffset / (nextOffset - prevOffset); … … 244 222 245 223 for (auto& stop : stops) 246 stop.offset /= scale;224 *stop.offset /= scale; 247 225 248 226 m_data.startRadius *= scale; … … 265 243 size_t firstZeroOrGreaterIndex = numStops; 266 244 for (size_t i = 0; i < numStops; ++i) { 267 if ( stops[i].offset >= 0) {245 if (*stops[i].offset >= 0) { 268 246 firstZeroOrGreaterIndex = i; 269 247 break; … … 272 250 273 251 if (firstZeroOrGreaterIndex > 0) { 274 if (firstZeroOrGreaterIndex < numStops && stops[firstZeroOrGreaterIndex].offset > 0) {275 float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;276 float nextOffset = stops[firstZeroOrGreaterIndex].offset;252 if (firstZeroOrGreaterIndex < numStops && *stops[firstZeroOrGreaterIndex].offset > 0) { 253 float prevOffset = *stops[firstZeroOrGreaterIndex - 1].offset; 254 float nextOffset = *stops[firstZeroOrGreaterIndex].offset; 277 255 278 256 float interStopProportion = -prevOffset / (nextOffset - prevOffset); … … 294 272 size_t lastOneOrLessIndex = numStops; 295 273 for (int i = numStops - 1; i >= 0; --i) { 296 if ( stops[i].offset <= 1) {274 if (*stops[i].offset <= 1) { 297 275 lastOneOrLessIndex = i; 298 276 break; … … 301 279 302 280 if (lastOneOrLessIndex < numStops - 1) { 303 if (lastOneOrLessIndex < numStops && stops[lastOneOrLessIndex].offset < 1) {304 float prevOffset = stops[lastOneOrLessIndex].offset;305 float nextOffset = stops[lastOneOrLessIndex + 1].offset;281 if (lastOneOrLessIndex < numStops && *stops[lastOneOrLessIndex].offset < 1) { 282 float prevOffset = *stops[lastOneOrLessIndex].offset; 283 float nextOffset = *stops[lastOneOrLessIndex + 1].offset; 306 284 307 285 float interStopProportion = (1 - prevOffset) / (nextOffset - prevOffset); … … 327 305 { 328 306 if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) { 329 sortStopsIfNeeded();330 331 307 Gradient::ColorStopVector result; 332 308 result.reserveInitialCapacity(m_stops.size()); … … 334 310 for (auto& stop : m_stops) { 335 311 float offset; 336 if (stop. m_position->isPercentage())337 offset = stop. m_position->floatValue(CSSUnitType::CSS_PERCENTAGE) / 100;312 if (stop.position->isPercentage()) 313 offset = stop.position->floatValue(CSSUnitType::CSS_PERCENTAGE) / 100; 338 314 else 339 offset = stop. m_position->floatValue(CSSUnitType::CSS_NUMBER);340 341 Color color = stop. m_resolvedColor;315 offset = stop.position->floatValue(CSSUnitType::CSS_NUMBER); 316 317 Color color = stop.resolvedColor; 342 318 if (style.hasAppleColorFilter()) 343 319 style.appleColorFilter().transformColor(color); … … 345 321 } 346 322 323 std::stable_sort(result.begin(), result.end(), [] (const Gradient::ColorStop& a, const Gradient::ColorStop& b) { 324 return a.offset < b.offset; 325 }); 326 347 327 return result; 348 328 } … … 356 336 auto& stop = m_stops[i]; 357 337 358 stops[i].isMidpoint = stop.isMidpoint; 359 360 Color color = stop.m_resolvedColor; 338 Color color = stop.resolvedColor; 361 339 if (style.hasAppleColorFilter()) 362 340 style.appleColorFilter().transformColor(color); … … 364 342 stops[i].color = color; 365 343 366 if (stop. m_position) {367 auto& positionValue = *stop. m_position;344 if (stop.position) { 345 auto& positionValue = *stop.position; 368 346 if (positionValue.isPercentage()) 369 347 stops[i].offset = positionValue.floatValue(CSSUnitType::CSS_PERCENTAGE) / 100; … … 383 361 stops[i].offset = 0; 384 362 } 385 stops[i].specified = true;386 363 } else { 387 364 // If the first color-stop does not have a position, its position defaults to 0%. 388 365 // If the last color-stop does not have a position, its position defaults to 100%. 389 if (!i) {366 if (!i) 390 367 stops[i].offset = 0; 391 stops[i].specified = true; 392 } else if (numStops > 1 && i == numStops - 1) { 368 else if (numStops > 1 && i == numStops - 1) 393 369 stops[i].offset = 1; 394 stops[i].specified = true;395 }396 370 } 397 371 … … 399 373 // color-stop before it in the list, its position is changed to be equal to the 400 374 // largest specified position of any color-stop before it. 401 if (stops[i]. specified&& i > 0) {375 if (stops[i].isSpecified() && i > 0) { 402 376 size_t prevSpecifiedIndex; 403 377 for (prevSpecifiedIndex = i - 1; prevSpecifiedIndex; --prevSpecifiedIndex) { 404 if (stops[prevSpecifiedIndex]. specified)378 if (stops[prevSpecifiedIndex].isSpecified()) 405 379 break; 406 380 } 407 381 408 if ( stops[i].offset <stops[prevSpecifiedIndex].offset)382 if (*stops[i].offset < *stops[prevSpecifiedIndex].offset) 409 383 stops[i].offset = stops[prevSpecifiedIndex].offset; 410 384 } 411 385 } 412 386 413 ASSERT(stops[0]. specified && stops[numStops - 1].specified);387 ASSERT(stops[0].isSpecified() && stops[numStops - 1].isSpecified()); 414 388 415 389 // If any color-stop still does not have a position, then, for each run of adjacent … … 421 395 422 396 for (size_t i = 0; i < numStops; ++i) { 423 if (!stops[i]. specified&& !inUnspecifiedRun) {397 if (!stops[i].isSpecified() && !inUnspecifiedRun) { 424 398 unspecifiedRunStart = i; 425 399 inUnspecifiedRun = true; 426 } else if (stops[i]. specified&& inUnspecifiedRun) {400 } else if (stops[i].isSpecified() && inUnspecifiedRun) { 427 401 size_t unspecifiedRunEnd = i; 428 402 429 403 if (unspecifiedRunStart < unspecifiedRunEnd) { 430 float lastSpecifiedOffset = stops[unspecifiedRunStart - 1].offset;431 float nextSpecifiedOffset = stops[unspecifiedRunEnd].offset;404 float lastSpecifiedOffset = *stops[unspecifiedRunStart - 1].offset; 405 float nextSpecifiedOffset = *stops[unspecifiedRunEnd].offset; 432 406 float delta = (nextSpecifiedOffset - lastSpecifiedOffset) / (unspecifiedRunEnd - unspecifiedRunStart + 1); 433 407 … … 455 429 // extra stops and generate hard lines. 456 430 for (size_t x = 1; x < stops.size() - 1;) { 457 if (!stops[x].isMidpoint ) {431 if (!stops[x].isMidpoint()) { 458 432 ++x; 459 433 continue; … … 465 439 Color color2 = stops[x + 1].color; 466 440 // Likewise find the position of previous and next color stop. 467 float offset1 = stops[x - 1].offset;468 float offset2 = stops[x + 1].offset;469 float offset = stops[x].offset;441 float offset1 = *stops[x - 1].offset; 442 float offset2 = *stops[x + 1].offset; 443 float offset = *stops[x].offset; 470 444 471 445 // Check if everything coincides or the midpoint is exactly in the middle. … … 480 454 // Morph the midpoint to a regular stop with the color of the next color stop. 481 455 stops[x].color = color2; 482 stops[x].isMidpoint = false;483 456 continue; 484 457 } … … 488 461 // Morph the midpoint to a regular stop with the color of the previous color stop. 489 462 stops[x].color = color1; 490 stops[x].isMidpoint = false;491 463 continue; 492 464 } … … 509 481 // calculate colors 510 482 for (size_t y = 0; y < 9; ++y) { 511 float relativeOffset = ( newStops[y].offset - offset1) / (offset2 - offset1);483 float relativeOffset = (*newStops[y].offset - offset1) / (offset2 - offset1); 512 484 float multiplier = std::pow(relativeOffset, std::log(.5f) / std::log(midpoint)); 513 485 // FIXME: Why not premultiply here? … … 528 500 // If the difference in the positions of the first and last color-stops is 0, 529 501 // the gradient defines a solid-color image with the color of the last color-stop in the rule. 530 float gradientRange = stops.last().offset -stops.first().offset;502 float gradientRange = *stops.last().offset - *stops.first().offset; 531 503 if (!gradientRange) { 532 504 stops.first().offset = 0; … … 541 513 542 514 // Work backwards from the first, adding stops until we get one before 0. 543 float firstOffset = stops[0].offset;515 float firstOffset = *stops[0].offset; 544 516 if (firstOffset > 0) { 545 517 float currOffset = firstOffset; … … 555 527 556 528 if (srcStopOrdinal) 557 currOffset -= stops[originalFirstStopIndex + srcStopOrdinal].offset -stops[originalFirstStopIndex + srcStopOrdinal - 1].offset;529 currOffset -= *stops[originalFirstStopIndex + srcStopOrdinal].offset - *stops[originalFirstStopIndex + srcStopOrdinal - 1].offset; 558 530 srcStopOrdinal = (srcStopOrdinal + originalNumStops - 1) % originalNumStops; 559 531 } … … 561 533 562 534 // Work forwards from the end, adding stops until we get one after 1. 563 float lastOffset = stops[stops.size() - 1].offset;535 float lastOffset = *stops[stops.size() - 1].offset; 564 536 if (lastOffset < maxExtent) { 565 537 float currOffset = lastOffset; … … 574 546 break; 575 547 if (srcStopOrdinal < originalNumStops - 1) 576 currOffset += stops[srcStopIndex + 1].offset -stops[srcStopIndex].offset;548 currOffset += *stops[srcStopIndex + 1].offset - *stops[srcStopIndex].offset; 577 549 srcStopOrdinal = (srcStopOrdinal + 1) % originalNumStops; 578 550 } … … 582 554 583 555 // If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops. 584 if (stops.size() > 1 && ( stops.first().offset < 0 ||stops.last().offset > 1))556 if (stops.size() > 1 && (*stops.first().offset < 0 || *stops.last().offset > 1)) 585 557 gradientAdapter.normalizeStopsAndEndpointsOutsideRange(stops); 586 558 … … 588 560 result.reserveInitialCapacity(stops.size()); 589 561 for (auto& stop : stops) 590 result.uncheckedAppend({ stop.offset, stop.color });562 result.uncheckedAppend({ *stop.offset, stop.color }); 591 563 592 564 return result; … … 595 567 static float positionFromValue(const CSSPrimitiveValue* value, const CSSToLengthConversionData& conversionData, const FloatSize& size, bool isHorizontal) 596 568 { 597 int origin = 0; 598 int sign = 1; 599 int edgeDistance = isHorizontal ? size.width() : size.height(); 600 569 if (!value) 570 return 0; 571 572 float origin = 0; 573 float sign = 1; 574 float edgeDistance = isHorizontal ? size.width() : size.height(); 575 601 576 // In this case the center of the gradient is given relative to an edge in the 602 577 // form of: [ top | bottom | right | left ] [ <percentage> | <length> ]. 603 578 if (value->isPair()) { 604 579 CSSValueID originID = value->pairValue()->first()->valueID(); 605 value = value->pairValue()->second();606 607 580 if (originID == CSSValueRight || originID == CSSValueBottom) { 608 581 // For right/bottom, the offset is relative to the far edge. … … 610 583 sign = -1; 611 584 } 612 } 613 585 value = value->pairValue()->second(); 586 } 587 614 588 if (value->isNumber()) 615 589 return origin + sign * value->floatValue() * conversionData.zoom(); 616 590 617 591 if (value->isPercentage()) 618 return origin + sign * value->floatValue() / 100.f * edgeDistance; 619 620 if (value->isCalculatedPercentageWithLength()) { 621 Ref<CalculationValue> calculationValue { value->cssCalcValue()->createCalculationValue(conversionData) }; 622 return origin + sign * calculationValue->evaluate(edgeDistance); 623 } 624 592 return origin + sign * value->floatValue() / 100 * edgeDistance; 593 594 if (value->isCalculatedPercentageWithLength()) 595 return origin + sign * value->cssCalcValue()->createCalculationValue(conversionData)->evaluate(edgeDistance); 596 625 597 switch (value->valueID()) { 626 598 case CSSValueTop: … … 632 604 case CSSValueBottom: 633 605 ASSERT(!isHorizontal); 634 return size.height();606 return edgeDistance; 635 607 case CSSValueRight: 636 608 ASSERT(isHorizontal); 637 return size.width();609 return edgeDistance; 638 610 case CSSValueCenter: 639 611 return origin + sign * .5f * edgeDistance; … … 645 617 } 646 618 647 FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSPrimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const FloatSize& size) 648 { 649 FloatPoint result; 650 651 if (horizontal) 652 result.setX(positionFromValue(horizontal, conversionData, size, true)); 653 654 if (vertical) 655 result.setY(positionFromValue(vertical, conversionData, size, false)); 656 657 return result; 619 // Resolve points/radii to front end values. 620 static FloatPoint computeEndPoint(const CSSPrimitiveValue* horizontal, const CSSPrimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const FloatSize& size) 621 { 622 return { positionFromValue(horizontal, conversionData, size, true), positionFromValue(vertical, conversionData, size, false) }; 658 623 } 659 624 660 625 bool CSSGradientValue::isCacheable() const 661 626 { 627 if (hasColorDerivedFromElement()) 628 return false; 662 629 for (auto& stop : m_stops) { 663 if (stop. m_colorIsDerivedFromElement)630 if (stop.position && stop.position->isFontRelativeLength()) 664 631 return false; 665 666 if (!stop.m_position) 667 continue; 668 669 if (stop.m_position->isFontRelativeLength()) 632 } 633 return true; 634 } 635 636 bool CSSGradientValue::knownToBeOpaque(const RenderElement& renderer) const 637 { 638 bool hasColorFilter = renderer.style().hasAppleColorFilter(); 639 for (auto& stop : m_stops) { 640 Color color = stop.resolvedColor; 641 if (hasColorFilter) 642 renderer.style().appleColorFilter().transformColor(color); 643 if (!color.isOpaque()) 670 644 return false; 671 645 } 672 673 646 return true; 674 647 } 675 648 676 bool CSSGradientValue::knownToBeOpaque(const RenderElement& renderer) const 677 { 678 bool hasColorFilter = renderer.style().hasAppleColorFilter(); 679 680 for (auto& stop : m_stops) { 681 if (hasColorFilter) { 682 Color stopColor = stop.m_resolvedColor; 683 renderer.style().appleColorFilter().transformColor(stopColor); 684 if (!stopColor.isOpaque()) 685 return false; 686 } 687 688 if (!stop.m_resolvedColor.isOpaque()) 689 return false; 690 } 691 return true; 649 bool CSSGradientValue::equals(const CSSGradientValue& other) const 650 { 651 return compareCSSValuePtr(m_firstX, other.m_firstX) 652 && compareCSSValuePtr(m_firstY, other.m_firstY) 653 && compareCSSValuePtr(m_secondX, other.m_secondX) 654 && compareCSSValuePtr(m_secondY, other.m_secondY) 655 && m_stops == other.m_stops 656 && m_gradientType == other.m_gradientType 657 && m_repeating == other.m_repeating; 692 658 } 693 659 … … 695 661 { 696 662 for (auto& stop : stops) { 697 double position = stop. m_position->doubleValue(CSSUnitType::CSS_NUMBER);663 double position = stop.position->doubleValue(CSSUnitType::CSS_NUMBER); 698 664 if (!position) 699 builder.append(", from(", stop. m_color->cssText(), ')');665 builder.append(", from(", stop.color->cssText(), ')'); 700 666 else if (position == 1) 701 builder.append(", to(", stop. m_color->cssText(), ')');667 builder.append(", to(", stop.color->cssText(), ')'); 702 668 else 703 builder.append(", color-stop(", position, ", ", stop.m_color->cssText(), ')'); 704 } 705 } 706 707 void CSSGradientValue::writeColorStop(StringBuilder& builder, const CSSGradientColorStop& stop) const 708 { 709 if (!stop.isMidpoint && stop.m_color) 710 builder.append(stop.m_color->cssText()); 711 712 if (stop.m_position) { 713 if (!stop.isMidpoint) 714 builder.append(' '); 715 builder.append(stop.m_position->cssText()); 716 } 669 builder.append(", color-stop(", position, ", ", stop.color->cssText(), ')'); 670 } 671 } 672 673 template<typename T, typename U> static void appendSpaceSeparatedOptionalCSSPtrText(StringBuilder& builder, const T& a, const U& b) 674 { 675 if (a && b) 676 builder.append(a->cssText(), ' ', b->cssText()); 677 else if (a) 678 builder.append(a->cssText()); 679 else if (b) 680 builder.append(b->cssText()); 681 } 682 683 static void writeColorStop(StringBuilder& builder, const CSSGradientColorStop& stop) 684 { 685 appendSpaceSeparatedOptionalCSSPtrText(builder, stop.color, stop.position); 717 686 } 718 687 … … 720 689 { 721 690 StringBuilder result; 722 if ( m_gradientType== CSSDeprecatedLinearGradient) {723 result.append("-webkit-gradient(linear, ", m_firstX->cssText(), ' ', m_firstY->cssText(), ", ", m_secondX->cssText(), ' ', m_secondY->cssText());724 appendGradientStops(result, m_stops);725 } else if ( m_gradientType== CSSPrefixedLinearGradient) {726 if ( m_repeating)691 if (gradientType() == CSSDeprecatedLinearGradient) { 692 result.append("-webkit-gradient(linear, ", firstX()->cssText(), ' ', firstY()->cssText(), ", ", secondX()->cssText(), ' ', secondY()->cssText()); 693 appendGradientStops(result, stops()); 694 } else if (gradientType() == CSSPrefixedLinearGradient) { 695 if (isRepeating()) 727 696 result.appendLiteral("-webkit-repeating-linear-gradient("); 728 697 else … … 731 700 if (m_angle) 732 701 result.append(m_angle->cssText()); 733 else { 734 if (m_firstX && m_firstY) 735 result.append(m_firstX->cssText(), ' ', m_firstY->cssText()); 736 else if (m_firstX) 737 result.append(m_firstX->cssText()); 738 else if (m_firstY) 739 result.append(m_firstY->cssText()); 740 } 741 742 for (auto& stop : m_stops) { 702 else 703 appendSpaceSeparatedOptionalCSSPtrText(result, firstX(), firstY()); 704 705 for (auto& stop : stops()) { 743 706 result.appendLiteral(", "); 744 707 writeColorStop(result, stop); 745 708 } 746 709 } else { 747 if ( m_repeating)710 if (isRepeating()) 748 711 result.appendLiteral("repeating-linear-gradient("); 749 712 else … … 755 718 result.append(m_angle->cssText()); 756 719 wroteSomething = true; 757 } else if (( m_firstX || m_firstY) && !(!m_firstX && m_firstY && m_firstY->valueID() == CSSValueBottom)) {720 } else if ((firstX() || firstY()) && !(!firstX() && firstY() && firstY()->valueID() == CSSValueBottom)) { 758 721 result.appendLiteral("to "); 759 if (m_firstX && m_firstY) 760 result.append(m_firstX->cssText(), ' ', m_firstY->cssText()); 761 else if (m_firstX) 762 result.append(m_firstX->cssText()); 763 else 764 result.append(m_firstY->cssText()); 722 appendSpaceSeparatedOptionalCSSPtrText(result, firstX(), firstY()); 765 723 wroteSomething = true; 766 724 } 767 725 768 if (wroteSomething) 769 result.appendLiteral(", "); 770 771 bool wroteFirstStop = false; 772 for (auto& stop : m_stops) { 773 if (wroteFirstStop) 726 for (auto& stop : stops()) { 727 if (wroteSomething) 774 728 result.appendLiteral(", "); 775 wrote FirstStop= true;729 wroteSomething = true; 776 730 writeColorStop(result, stop); 777 731 } … … 860 814 if (m_angle) { 861 815 float angle = m_angle->floatValue(CSSUnitType::CSS_DEG); 862 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType);816 endPointsFromAngle(angle, size, firstPoint, secondPoint, gradientType()); 863 817 } else { 864 switch ( m_gradientType) {818 switch (gradientType()) { 865 819 case CSSDeprecatedLinearGradient: 866 firstPoint = computeEndPoint( m_firstX.get(), m_firstY.get(), conversionData, size);867 if ( m_secondX || m_secondY)868 secondPoint = computeEndPoint( m_secondX.get(), m_secondY.get(), conversionData, size);820 firstPoint = computeEndPoint(firstX(), firstY(), conversionData, size); 821 if (secondX() || secondY()) 822 secondPoint = computeEndPoint(secondX(), secondY(), conversionData, size); 869 823 else { 870 if ( m_firstX)824 if (firstX()) 871 825 secondPoint.setX(size.width() - firstPoint.x()); 872 if ( m_firstY)826 if (firstY()) 873 827 secondPoint.setY(size.height() - firstPoint.y()); 874 828 } 875 829 break; 876 830 case CSSPrefixedLinearGradient: 877 firstPoint = computeEndPoint( m_firstX.get(), m_firstY.get(), conversionData, size);878 if ( m_firstX)831 firstPoint = computeEndPoint(firstX(), firstY(), conversionData, size); 832 if (firstX()) 879 833 secondPoint.setX(size.width() - firstPoint.x()); 880 if ( m_firstY)834 if (firstY()) 881 835 secondPoint.setY(size.height() - firstPoint.y()); 882 836 break; 883 837 case CSSLinearGradient: 884 if ( m_firstX && m_firstY) {838 if (firstX() && firstY()) { 885 839 // "Magic" corners, so the 50% line touches two corners. 886 840 float rise = size.width(); 887 841 float run = size.height(); 888 if ( m_firstX && m_firstX->valueID() == CSSValueLeft)842 if (firstX() && firstX()->valueID() == CSSValueLeft) 889 843 run *= -1; 890 if ( m_firstY && m_firstY->valueID() == CSSValueBottom)844 if (firstY() && firstY()->valueID() == CSSValueBottom) 891 845 rise *= -1; 892 846 // Compute angle, and flip it back to "bearing angle" degrees. 893 847 float angle = 90 - rad2deg(atan2(rise, run)); 894 endPointsFromAngle(angle, size, firstPoint, secondPoint, m_gradientType);895 } else if ( m_firstX || m_firstY) {896 secondPoint = computeEndPoint( m_firstX.get(), m_firstY.get(), conversionData, size);897 if ( m_firstX)848 endPointsFromAngle(angle, size, firstPoint, secondPoint, gradientType()); 849 } else if (firstX() || firstY()) { 850 secondPoint = computeEndPoint(firstX(), firstY(), conversionData, size); 851 if (firstX()) 898 852 firstPoint.setX(size.width() - secondPoint.x()); 899 if ( m_firstY)853 if (firstY()) 900 854 firstPoint.setY(size.height() - secondPoint.y()); 901 855 } else … … 918 872 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const 919 873 { 920 if (m_gradientType == CSSDeprecatedLinearGradient) 921 return other.m_gradientType == m_gradientType 922 && compareCSSValuePtr(m_firstX, other.m_firstX) 923 && compareCSSValuePtr(m_firstY, other.m_firstY) 924 && compareCSSValuePtr(m_secondX, other.m_secondX) 925 && compareCSSValuePtr(m_secondY, other.m_secondY) 926 && m_stops == other.m_stops; 927 928 if (m_gradientType != other.m_gradientType) 929 return false; 930 931 if (m_repeating != other.m_repeating) 932 return false; 933 934 if (m_angle) 935 return compareCSSValuePtr(m_angle, other.m_angle) && m_stops == other.m_stops; 936 937 if (other.m_angle) 938 return false; 939 940 bool equalXandY = false; 941 if (m_firstX && m_firstY) 942 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && compareCSSValuePtr(m_firstY, other.m_firstY); 943 else if (m_firstX) 944 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY; 945 else if (m_firstY) 946 equalXandY = compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX; 947 else 948 equalXandY = !other.m_firstX && !other.m_firstY; 949 950 return equalXandY && m_stops == other.m_stops; 874 return CSSGradientValue::equals(other) && compareCSSValuePtr(m_angle, other.m_angle); 951 875 } 952 876 … … 955 879 StringBuilder result; 956 880 957 if ( m_gradientType== CSSDeprecatedRadialGradient) {958 result.append("-webkit-gradient(radial, ", m_firstX->cssText(), ' ', m_firstY->cssText(), ", ", m_firstRadius->cssText(),959 ", ", m_secondX->cssText(), ' ', m_secondY->cssText(), ", ", m_secondRadius->cssText());960 appendGradientStops(result, m_stops);961 } else if ( m_gradientType== CSSPrefixedRadialGradient) {962 if ( m_repeating)881 if (gradientType() == CSSDeprecatedRadialGradient) { 882 result.append("-webkit-gradient(radial, ", firstX()->cssText(), ' ', firstY()->cssText(), ", ", m_firstRadius->cssText(), 883 ", ", secondX()->cssText(), ' ', secondY()->cssText(), ", ", m_secondRadius->cssText()); 884 appendGradientStops(result, stops()); 885 } else if (gradientType() == CSSPrefixedRadialGradient) { 886 if (isRepeating()) 963 887 result.appendLiteral("-webkit-repeating-radial-gradient("); 964 888 else 965 889 result.appendLiteral("-webkit-radial-gradient("); 966 890 967 if (m_firstX && m_firstY) 968 result.append(m_firstX->cssText(), ' ', m_firstY->cssText()); 969 else if (m_firstX) 970 result.append(m_firstX->cssText()); 971 else if (m_firstY) 972 result.append(m_firstY->cssText()); 891 if (firstX() || firstY()) 892 appendSpaceSeparatedOptionalCSSPtrText(result, firstX(), firstY()); 973 893 else 974 894 result.appendLiteral("center"); … … 987 907 result.append(", ", m_endHorizontalSize->cssText(), ' ', m_endVerticalSize->cssText()); 988 908 989 for (auto& stop : m_stops) {909 for (auto& stop : stops()) { 990 910 result.appendLiteral(", "); 991 911 writeColorStop(result, stop); 992 912 } 993 913 } else { 994 if ( m_repeating)914 if (isRepeating()) 995 915 result.appendLiteral("repeating-radial-gradient("); 996 916 else … … 1020 940 } 1021 941 1022 if ( m_firstX || m_firstY) {942 if (firstX() || firstY()) { 1023 943 if (wroteSomething) 1024 944 result.append(' '); 1025 945 result.appendLiteral("at "); 1026 if (m_firstX && m_firstY) 1027 result.append(m_firstX->cssText(), ' ', m_firstY->cssText()); 1028 else if (m_firstX) 1029 result.append(m_firstX->cssText()); 1030 else 1031 result.append(m_firstY->cssText()); 946 appendSpaceSeparatedOptionalCSSPtrText(result, firstX(), firstY()); 1032 947 wroteSomething = true; 1033 948 } … … 1037 952 1038 953 bool wroteFirstStop = false; 1039 for (auto& stop : m_stops) {954 for (auto& stop : stops()) { 1040 955 if (wroteFirstStop) 1041 956 result.appendLiteral(", "); … … 1144 1059 CSSToLengthConversionData conversionData(&renderer.style(), renderer.document().documentElement()->renderStyle(), &renderer.view()); 1145 1060 1146 FloatPoint firstPoint = computeEndPoint( m_firstX.get(), m_firstY.get(), conversionData, size);1147 if (! m_firstX)1061 FloatPoint firstPoint = computeEndPoint(firstX(), firstY(), conversionData, size); 1062 if (!firstX()) 1148 1063 firstPoint.setX(size.width() / 2); 1149 if (! m_firstY)1064 if (!firstY()) 1150 1065 firstPoint.setY(size.height() / 2); 1151 1066 1152 FloatPoint secondPoint = computeEndPoint( m_secondX.get(), m_secondY.get(), conversionData, size);1153 if (! m_secondX)1067 FloatPoint secondPoint = computeEndPoint(secondX(), secondY(), conversionData, size); 1068 if (!secondX()) 1154 1069 secondPoint.setX(size.width() / 2); 1155 if (! m_secondY)1070 if (!secondY()) 1156 1071 secondPoint.setY(size.height() / 2); 1157 1072 … … 1267 1182 // computeStops() only uses maxExtent for repeating gradients. 1268 1183 float maxExtent = 0; 1269 if ( m_repeating) {1184 if (isRepeating()) { 1270 1185 FloatPoint corner; 1271 1186 maxExtent = distanceToFarthestCorner(secondPoint, size, corner); … … 1283 1198 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const 1284 1199 { 1285 if (m_gradientType == CSSDeprecatedRadialGradient) 1286 return other.m_gradientType == m_gradientType 1287 && compareCSSValuePtr(m_firstX, other.m_firstX) 1288 && compareCSSValuePtr(m_firstY, other.m_firstY) 1289 && compareCSSValuePtr(m_secondX, other.m_secondX) 1290 && compareCSSValuePtr(m_secondY, other.m_secondY) 1291 && compareCSSValuePtr(m_firstRadius, other.m_firstRadius) 1292 && compareCSSValuePtr(m_secondRadius, other.m_secondRadius) 1293 && m_stops == other.m_stops; 1294 1295 if (m_gradientType != other.m_gradientType) 1296 return false; 1297 1298 if (m_repeating != other.m_repeating) 1299 return false; 1300 1301 bool equalXandY = false; 1302 if (m_firstX && m_firstY) 1303 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && compareCSSValuePtr(m_firstY, other.m_firstY); 1304 else if (m_firstX) 1305 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY; 1306 else if (m_firstY) 1307 equalXandY = compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX; 1308 else 1309 equalXandY = !other.m_firstX && !other.m_firstY; 1310 1311 if (!equalXandY) 1312 return false; 1313 1314 bool equalShape = true; 1315 bool equalSizingBehavior = true; 1316 bool equalHorizontalAndVerticalSize = true; 1317 1318 if (m_shape) 1319 equalShape = compareCSSValuePtr(m_shape, other.m_shape); 1320 else if (m_sizingBehavior) 1321 equalSizingBehavior = compareCSSValuePtr(m_sizingBehavior, other.m_sizingBehavior); 1322 else if (m_endHorizontalSize && m_endVerticalSize) 1323 equalHorizontalAndVerticalSize = compareCSSValuePtr(m_endHorizontalSize, other.m_endHorizontalSize) && compareCSSValuePtr(m_endVerticalSize, other.m_endVerticalSize); 1324 else { 1325 equalShape = !other.m_shape; 1326 equalSizingBehavior = !other.m_sizingBehavior; 1327 equalHorizontalAndVerticalSize = !other.m_endHorizontalSize && !other.m_endVerticalSize; 1328 } 1329 return equalShape && equalSizingBehavior && equalHorizontalAndVerticalSize && m_stops == other.m_stops; 1330 } 1331 1200 return CSSGradientValue::equals(other) 1201 && compareCSSValuePtr(m_shape, other.m_shape) 1202 && compareCSSValuePtr(m_sizingBehavior, other.m_sizingBehavior) 1203 && compareCSSValuePtr(m_endHorizontalSize, other.m_endHorizontalSize) 1204 && compareCSSValuePtr(m_endVerticalSize, other.m_endVerticalSize); 1205 } 1332 1206 1333 1207 String CSSConicGradientValue::customCSSText() const … … 1335 1209 StringBuilder result; 1336 1210 1337 if ( m_repeating)1211 if (isRepeating()) 1338 1212 result.appendLiteral("repeating-conic-gradient("); 1339 1213 else … … 1347 1221 } 1348 1222 1349 if ( m_firstX && m_firstY) {1223 if (firstX() && firstY()) { 1350 1224 if (wroteSomething) 1351 1225 result.append(' '); 1352 result.append("at ", m_firstX->cssText(), ' ', m_firstY->cssText()); 1226 result.appendLiteral("at "); 1227 appendSpaceSeparatedOptionalCSSPtrText(result, firstX(), firstY()); 1353 1228 wroteSomething = true; 1354 1229 } … … 1358 1233 1359 1234 bool wroteFirstStop = false; 1360 for (auto& stop : m_stops) {1235 for (auto& stop : stops()) { 1361 1236 if (wroteFirstStop) 1362 1237 result.appendLiteral(", "); … … 1375 1250 CSSToLengthConversionData conversionData(&renderer.style(), renderer.document().documentElement()->renderStyle(), &renderer.view()); 1376 1251 1377 FloatPoint centerPoint = computeEndPoint( m_firstX.get(), m_firstY.get(), conversionData, size);1378 if (! m_firstX)1252 FloatPoint centerPoint = computeEndPoint(firstX(), firstY(), conversionData, size); 1253 if (!firstX()) 1379 1254 centerPoint.setX(size.width() / 2); 1380 if (! m_firstY)1255 if (!firstY()) 1381 1256 centerPoint.setY(size.height() / 2); 1382 1257 … … 1396 1271 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const 1397 1272 { 1398 if (m_repeating != other.m_repeating) 1399 return false; 1400 1401 if (!compareCSSValuePtr(m_angle, other.m_angle)) 1402 return false; 1403 1404 bool equalXandY = false; 1405 if (m_firstX && m_firstY) 1406 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && compareCSSValuePtr(m_firstY, other.m_firstY); 1407 else if (m_firstX) 1408 equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY; 1409 else if (m_firstY) 1410 equalXandY = compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX; 1411 else 1412 equalXandY = !other.m_firstX && !other.m_firstY; 1413 1414 return equalXandY && m_stops == other.m_stops; 1273 return CSSGradientValue::equals(other) && compareCSSValuePtr(m_angle, other.m_angle); 1415 1274 } 1416 1275
Note:
See TracChangeset
for help on using the changeset viewer.