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

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

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

Powered by Google App Engine
This is Rietveld 408576698