diff --git a/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch b/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch index 41283b3c18ae..c18b4dfd9800 100644 --- a/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch +++ b/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch @@ -400,7 +400,7 @@ index b147b8d321d865295007516b15d0aaccfc6f7fac..8f54a3a657c660a52fcd4c94865ca219 // A Corner is a axis-aligned quad, with the points ordered (start, outer, diff --git a/third_party/blink/renderer/platform/geometry/path_builder.cc b/third_party/blink/renderer/platform/geometry/path_builder.cc -index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d42368b2e 100644 +index 346cfc0b13b31808fbe1381b3785150810f347bb..ebb2be8cc3bb71c4df6526d743a851121e36c138 100644 --- a/third_party/blink/renderer/platform/geometry/path_builder.cc +++ b/third_party/blink/renderer/platform/geometry/path_builder.cc @@ -4,6 +4,7 @@ @@ -411,7 +411,7 @@ index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d #include "third_party/blink/renderer/platform/geometry/contoured_rect.h" #include "third_party/blink/renderer/platform/geometry/infinite_int_rect.h" #include "third_party/blink/renderer/platform/geometry/path.h" -@@ -231,6 +232,19 @@ PathBuilder& PathBuilder::AddContouredRect( +@@ -231,6 +232,26 @@ PathBuilder& PathBuilder::AddContouredRect( AddRoundedRect(target_rect); return *this; } @@ -419,12 +419,19 @@ index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d + // TODO(clavin): decompose `electron::DrawSmoothRoundRect` into corners + if (contoured_rect.GetCornerCurvature().IsSmooth()) { + const gfx::RectF& box = contoured_rect.Rect(); -+ const FloatRoundedRect::Radii& radii = contoured_rect.GetRadii(); ++ ++ // Constrain the radii (on a copy) to ensure they do not exceed the box. ++ FloatRoundedRect round_rect_copy = contoured_rect.AsRoundedRect(); ++ round_rect_copy.ConstrainRadii(); ++ const FloatRoundedRect::Radii& radii = round_rect_copy.GetRadii(); ++ float smoothness = std::clamp( ++ contoured_rect.GetCornerCurvature().Smoothness(), 0.0f, 1.0f); ++ + builder_.addPath(electron::DrawSmoothRoundRect( -+ box.x(), box.y(), box.width(), box.height(), -+ std::min(contoured_rect.GetCornerCurvature().Smoothness(), 1.0f), ++ box.x(), box.y(), box.width(), box.height(), smoothness, + radii.TopLeft().width(), radii.TopRight().width(), + radii.BottomRight().width(), radii.BottomLeft().width())); ++ + return *this; + } + diff --git a/shell/renderer/electron_smooth_round_rect.cc b/shell/renderer/electron_smooth_round_rect.cc index dcd681387c1f..e78f7cf0df43 100644 --- a/shell/renderer/electron_smooth_round_rect.cc +++ b/shell/renderer/electron_smooth_round_rect.cc @@ -100,10 +100,23 @@ constexpr CurveGeometry::CurveGeometry(float radius, float smoothness) { void DrawCorner(SkPath& path, float radius, - const CurveGeometry& curve1, - const CurveGeometry& curve2, + float smoothness1, + float smoothness2, const SkPoint& corner, unsigned int quarter_rotations) { + // If the radius is 0 then we can simply draw a line to the corner point. + if (radius == 0.0f) { + if (quarter_rotations == 0) { + path.moveTo(corner); + } else { + path.lineTo(corner); + } + return; + } + + CurveGeometry curve1(radius, smoothness1); + CurveGeometry curve2(radius, smoothness2); + // Move/Line to the edge connecting point { SkPoint edge_connecting_point = @@ -160,6 +173,12 @@ constexpr std::pair ConstrainSmoothness(float size, float smoothness, float radius1, float radius2) { + // If both radii are 0 then we don't need any smoothing. This avoids a + // division by zero in the ratio calculation. + if (radius1 == 0.0f && radius2 == 0.0f) { + return {0.0f, 0.0f}; + } + float edge_consumed1 = LengthForCornerSmoothness(smoothness, radius1); float edge_consumed2 = LengthForCornerSmoothness(smoothness, radius2); @@ -269,28 +288,20 @@ SkPath DrawSmoothRoundRect(float x, SkPath path; // Top left corner - DrawCorner(path, top_left_radius, - CurveGeometry(top_left_radius, left_top_smoothness), - CurveGeometry(top_left_radius, top_left_smoothness), + DrawCorner(path, top_left_radius, left_top_smoothness, top_left_smoothness, SkPoint::Make(x, y), 0); // Top right corner - DrawCorner(path, top_right_radius, - CurveGeometry(top_right_radius, top_right_smoothness), - CurveGeometry(top_right_radius, right_top_smoothness), + DrawCorner(path, top_right_radius, top_right_smoothness, right_top_smoothness, SkPoint::Make(x + width, y), 1); // Bottom right corner - DrawCorner(path, bottom_right_radius, - CurveGeometry(bottom_right_radius, right_bottom_smoothness), - CurveGeometry(bottom_right_radius, bottom_right_smoothness), - SkPoint::Make(x + width, y + height), 2); + DrawCorner(path, bottom_right_radius, right_bottom_smoothness, + bottom_right_smoothness, SkPoint::Make(x + width, y + height), 2); // Bottom left corner - DrawCorner(path, bottom_left_radius, - CurveGeometry(bottom_left_radius, bottom_left_smoothness), - CurveGeometry(bottom_left_radius, left_bottom_smoothness), - SkPoint::Make(x, y + height), 3); + DrawCorner(path, bottom_left_radius, left_bottom_smoothness, + bottom_left_smoothness, SkPoint::Make(x, y + height), 3); path.close(); return path; diff --git a/spec/api-corner-smoothing-spec.ts b/spec/api-corner-smoothing-spec.ts index a25a787db762..2ca9285832a2 100644 --- a/spec/api-corner-smoothing-spec.ts +++ b/spec/api-corner-smoothing-spec.ts @@ -6,7 +6,6 @@ import { AssertionError, expect } from 'chai'; import path = require('node:path'); import { createArtifact } from './lib/artifacts'; -import { ifdescribe } from './lib/spec-helpers'; import { closeAllWindows } from './lib/window-helpers'; const FIXTURE_PATH = path.resolve( @@ -42,7 +41,7 @@ const COMPARISON_TOLERANCE = 2.5; function compareImages (img1: NativeImage, img2: NativeImage): boolean { expect(img1.getSize()).to.deep.equal( img2.getSize(), - 'Cannot compare images with different sizes' + 'Cannot compare images with different sizes. Run tests with --force-device-scale-factor=1' ); const bitmap1 = img1.toBitmap(); @@ -119,9 +118,7 @@ async function pageCaptureTestRecipe ( } } -// FIXME: these tests rely on live rendering results, which are too variable to -// reproduce outside of CI, primarily due to display scaling. -ifdescribe(!!process.env.CI)('-electron-corner-smoothing', () => { +describe('-electron-corner-smoothing', () => { afterEach(async () => { await closeAllWindows(); }); diff --git a/spec/fixtures/api/corner-smoothing/shape/expected-false.png b/spec/fixtures/api/corner-smoothing/shape/expected-false.png index 31aea673f8b0..56c135d740af 100644 Binary files a/spec/fixtures/api/corner-smoothing/shape/expected-false.png and b/spec/fixtures/api/corner-smoothing/shape/expected-false.png differ diff --git a/spec/fixtures/api/corner-smoothing/shape/expected-true.png b/spec/fixtures/api/corner-smoothing/shape/expected-true.png index f48bc31e2886..97280d9369ce 100644 Binary files a/spec/fixtures/api/corner-smoothing/shape/expected-true.png and b/spec/fixtures/api/corner-smoothing/shape/expected-true.png differ diff --git a/spec/fixtures/api/corner-smoothing/shape/test.html b/spec/fixtures/api/corner-smoothing/shape/test.html index 994e1bd76ee2..d8db2ce0d495 100644 --- a/spec/fixtures/api/corner-smoothing/shape/test.html +++ b/spec/fixtures/api/corner-smoothing/shape/test.html @@ -44,7 +44,7 @@ } .box { - --boxes-x: 7; + --boxes-x: 8; --boxes-y: 5; --box-shadow-offset: 4px; --box-shadow-spread: 2px; @@ -84,6 +84,10 @@ background-color: skyblue; box-shadow: var(--box-shadow-offset) var(--box-shadow-offset) var(--box-shadow-spread) var(--box-shadow-grow) cornflowerblue; } + .box.multiple-radii { + background-color: coral; + border-radius: 0 0 calc((var(--box-size) / 8) - 2px) calc((var(--box-size) / 2) - 8px); + } @@ -95,6 +99,7 @@
+
@@ -104,6 +109,7 @@
+
@@ -113,6 +119,7 @@
+
@@ -122,6 +129,7 @@
+
@@ -131,6 +139,7 @@
+
\ No newline at end of file