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

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

Issue 2787113002: Initial conic-gradient() implementation (Closed)
Patch Set: baselines 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 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 if (m_gradientType == CSSDeprecatedLinearGradient || 451 if (m_gradientType == CSSDeprecatedLinearGradient ||
452 m_gradientType == CSSDeprecatedRadialGradient) { 452 m_gradientType == CSSDeprecatedRadialGradient) {
453 addDeprecatedStops(desc, object); 453 addDeprecatedStops(desc, object);
454 return; 454 return;
455 } 455 }
456 456
457 size_t numStops = m_stops.size(); 457 size_t numStops = m_stops.size();
458 458
459 Vector<GradientStop> stops(numStops); 459 Vector<GradientStop> stops(numStops);
460 460
461 float gradientLength;
462 switch (getClassType()) {
463 case LinearGradientClass:
464 gradientLength = FloatSize(desc.p1 - desc.p0).diagonalLength();
465 break;
466 case RadialGradientClass:
467 gradientLength = desc.r1;
468 break;
469 case ConicGradientClass:
470 gradientLength = 1;
471 break;
472 default:
473 NOTREACHED();
474 gradientLength = 0;
475 }
476
461 bool hasHints = false; 477 bool hasHints = false;
462
463 FloatPoint gradientStart = desc.p0;
464 FloatPoint gradientEnd;
465 if (isLinearGradientValue())
466 gradientEnd = desc.p1;
467 else if (isRadialGradientValue())
468 gradientEnd = gradientStart + FloatSize(desc.r1, 0);
469 float gradientLength =
470 FloatSize(gradientStart - gradientEnd).diagonalLength();
471
472 for (size_t i = 0; i < numStops; ++i) { 478 for (size_t i = 0; i < numStops; ++i) {
473 const CSSGradientColorStop& stop = m_stops[i]; 479 const CSSGradientColorStop& stop = m_stops[i];
474 480
475 if (stop.isHint()) 481 if (stop.isHint())
476 hasHints = true; 482 hasHints = true;
477 else 483 else
478 stops[i].color = resolveStopColor(*stop.m_color, object); 484 stops[i].color = resolveStopColor(*stop.m_color, object);
479 485
480 if (stop.m_offset) { 486 if (stop.m_offset) {
481 if (stop.m_offset->isPercentage()) { 487 if (stop.m_offset->isPercentage()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 565 }
560 } 566 }
561 567
562 ASSERT(stops.size() == m_stops.size()); 568 ASSERT(stops.size() == m_stops.size());
563 if (hasHints) { 569 if (hasHints) {
564 replaceColorHintsWithColorStops(stops, m_stops); 570 replaceColorHintsWithColorStops(stops, m_stops);
565 } 571 }
566 572
567 // At this point we have a fully resolved set of stops. Time to perform 573 // At this point we have a fully resolved set of stops. Time to perform
568 // adjustments for repeat gradients and degenerate values if needed. 574 // adjustments for repeat gradients and degenerate values if needed.
569 if (requiresStopsNormalization(stops, desc)) { 575 // Note: the normalization trick doesn't work for conic gradients, because
570 // Negative offsets are only an issue for non-repeating radial gradients: 576 // the underlying Skia implementation doesn't support tiling.
571 // linear gradient points can be repositioned arbitrarily, and for repeating 577 if (isConicGradientValue() || !requiresStopsNormalization(stops, desc)) {
572 // radial gradients we shift the radii into equivalent positive values. 578 // No normalization required, just add the current stops.
573 if (isRadialGradientValue() && !m_repeating) 579 for (const auto& stop : stops)
574 clampNegativeOffsets(stops); 580 desc.stops.emplace_back(stop.offset, stop.color);
581 return;
582 }
575 583
576 if (normalizeAndAddStops(stops, desc)) { 584 switch (getClassType()) {
577 if (isLinearGradientValue()) { 585 case LinearGradientClass:
586 if (normalizeAndAddStops(stops, desc)) {
578 adjustGradientPointsForOffsetRange(desc, stops.front().offset, 587 adjustGradientPointsForOffsetRange(desc, stops.front().offset,
579 stops.back().offset); 588 stops.back().offset);
580 } else { 589 }
590 break;
591 case RadialGradientClass:
592 // Negative offsets are only an issue for non-repeating radial gradients:
593 // linear gradient points can be repositioned arbitrarily, and for
594 // repeating radial gradients we shift the radii into equivalent positive
595 // values.
596 if (!m_repeating)
597 clampNegativeOffsets(stops);
598
599 if (normalizeAndAddStops(stops, desc)) {
581 adjustGradientRadiiForOffsetRange(desc, stops.front().offset, 600 adjustGradientRadiiForOffsetRange(desc, stops.front().offset,
582 stops.back().offset); 601 stops.back().offset);
583 } 602 }
584 } else { 603 break;
585 // Normalization failed because the stop set is coincident. 604 default:
586 } 605 NOTREACHED();
587 } else {
588 // No normalization required, just add the current stops.
589 for (const auto& stop : stops)
590 desc.stops.emplace_back(stop.offset, stop.color);
591 } 606 }
592 } 607 }
593 608
594 static float positionFromValue(const CSSValue* value, 609 static float positionFromValue(const CSSValue* value,
595 const CSSToLengthConversionData& conversionData, 610 const CSSToLengthConversionData& conversionData,
596 const IntSize& size, 611 const IntSize& size,
597 bool isHorizontal) { 612 bool isHorizontal) {
598 int origin = 0; 613 int origin = 0;
599 int sign = 1; 614 int sign = 1;
600 int edgeDistance = isHorizontal ? size.width() : size.height(); 615 int edgeDistance = isHorizontal ? size.width() : size.height();
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 result.append(')'); 1376 result.append(')');
1362 return result.toString(); 1377 return result.toString();
1363 } 1378 }
1364 1379
1365 PassRefPtr<Gradient> CSSConicGradientValue::createGradient( 1380 PassRefPtr<Gradient> CSSConicGradientValue::createGradient(
1366 const CSSToLengthConversionData& conversionData, 1381 const CSSToLengthConversionData& conversionData,
1367 const IntSize& size, 1382 const IntSize& size,
1368 const LayoutObject& object) { 1383 const LayoutObject& object) {
1369 DCHECK(!size.isEmpty()); 1384 DCHECK(!size.isEmpty());
1370 1385
1371 // TODO(fmalita): implement 1386 const float angle = m_fromAngle ? m_fromAngle->computeDegrees() : 0;
1372 return Gradient::createLinear(FloatPoint(), FloatPoint()); 1387
1388 const FloatPoint position(
1389 m_firstX ? positionFromValue(m_firstX, conversionData, size, true)
1390 : size.width() / 2,
1391 m_firstY ? positionFromValue(m_firstY, conversionData, size, false)
1392 : size.height() / 2);
1393
1394 GradientDesc desc(position, position,
1395 m_repeating ? SpreadMethodRepeat : SpreadMethodPad);
1396 addStops(desc, conversionData, object);
1397
1398 RefPtr<Gradient> gradient =
1399 Gradient::createConic(position, angle, desc.spreadMethod,
1400 Gradient::ColorInterpolation::Premultiplied);
1401 gradient->addColorStops(desc.stops);
1402
1403 return gradient.release();
1373 } 1404 }
1374 1405
1375 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const { 1406 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const {
1376 return m_repeating == other.m_repeating && 1407 return m_repeating == other.m_repeating &&
1377 dataEquivalent(m_firstX, other.m_firstX) && 1408 dataEquivalent(m_firstX, other.m_firstX) &&
1378 dataEquivalent(m_firstY, other.m_firstY) && 1409 dataEquivalent(m_firstY, other.m_firstY) &&
1379 dataEquivalent(m_fromAngle, other.m_fromAngle) && 1410 dataEquivalent(m_fromAngle, other.m_fromAngle) &&
1380 m_stops == other.m_stops; 1411 m_stops == other.m_stops;
1381 } 1412 }
1382 1413
1383 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) { 1414 DEFINE_TRACE_AFTER_DISPATCH(CSSConicGradientValue) {
1384 visitor->trace(m_fromAngle); 1415 visitor->trace(m_fromAngle);
1385 CSSGradientValue::traceAfterDispatch(visitor); 1416 CSSGradientValue::traceAfterDispatch(visitor);
1386 } 1417 }
1387 1418
1388 } // namespace blink 1419 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698